Bag of holding updates
199
vendor/json/test/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
option(JSON_Sanitizer "Build test suite with Clang sanitizer" OFF)
|
||||
option(JSON_Valgrind "Execute test suite with Valgrind" OFF)
|
||||
option(JSON_NoExceptions "Build test suite without exceptions" OFF)
|
||||
option(JSON_Coverage "Build test suite with coverage information" OFF)
|
||||
|
||||
# download test data
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/download_test_data.cmake)
|
||||
|
||||
# test fixture to download test data
|
||||
add_test(NAME "download_test_data" COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target download_test_data)
|
||||
set_tests_properties(download_test_data PROPERTIES FIXTURES_SETUP TEST_DATA)
|
||||
|
||||
if(JSON_Sanitizer)
|
||||
message(STATUS "Building test suite with Clang sanitizer")
|
||||
if(NOT MSVC)
|
||||
set(CMAKE_CXX_FLAGS "-g -O0 -fsanitize=address -fsanitize=undefined -fsanitize=integer -fsanitize=nullability -fno-omit-frame-pointer -fno-sanitize-recover=all -fsanitize-recover=unsigned-integer-overflow")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(JSON_Valgrind)
|
||||
find_program(CMAKE_MEMORYCHECK_COMMAND valgrind)
|
||||
message(STATUS "Executing test suite with Valgrind (${CMAKE_MEMORYCHECK_COMMAND})")
|
||||
set(memcheck_command "${CMAKE_MEMORYCHECK_COMMAND} ${CMAKE_MEMORYCHECK_COMMAND_OPTIONS} --error-exitcode=1 --leak-check=full")
|
||||
separate_arguments(memcheck_command)
|
||||
endif()
|
||||
|
||||
if(JSON_NoExceptions)
|
||||
message(STATUS "Building test suite without exceptions")
|
||||
if(NOT MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DJSON_NOEXCEPTION")
|
||||
endif()
|
||||
set(DOCTEST_TEST_FILTER --no-throw)
|
||||
endif()
|
||||
|
||||
if(JSON_Coverage)
|
||||
message(STATUS "Building test suite with coverage information")
|
||||
|
||||
# from https://github.com/RWTH-HPC/CMake-codecov/blob/master/cmake/FindGcov.cmake
|
||||
get_filename_component(COMPILER_PATH "${CMAKE_CXX_COMPILER}" PATH)
|
||||
string(REGEX MATCH "^[0-9]+" GCC_VERSION "${CMAKE_CXX_COMPILER_VERSION}")
|
||||
find_program(GCOV_BIN NAMES gcov-${GCC_VERSION} gcov HINTS ${COMPILER_PATH})
|
||||
|
||||
# collect all source files from the chosen include dir
|
||||
file(GLOB_RECURSE SOURCE_FILES ${NLOHMANN_JSON_INCLUDE_BUILD_DIR}*.hpp)
|
||||
|
||||
# add target to collect coverage information and generate HTML file
|
||||
# (filter script from https://stackoverflow.com/a/43726240/266378)
|
||||
add_custom_target(lcov_html
|
||||
COMMAND lcov --directory . --capture --output-file json.info --rc lcov_branch_coverage=1
|
||||
COMMAND lcov -e json.info ${SOURCE_FILES} --output-file json.info.filtered --gcov-tool ${GCOV_BIN} --rc lcov_branch_coverage=1
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/test/thirdparty/imapdl/filterbr.py json.info.filtered > json.info.filtered.noexcept
|
||||
COMMAND genhtml --title "JSON for Modern C++" --legend --demangle-cpp --output-directory html --show-details --branch-coverage json.info.filtered.noexcept
|
||||
COMMENT "Generating HTML report test/html/index.html"
|
||||
)
|
||||
endif()
|
||||
|
||||
#############################################################################
|
||||
# doctest library with the main function to speed up build
|
||||
#############################################################################
|
||||
|
||||
add_library(doctest_main OBJECT src/unit.cpp)
|
||||
set_target_properties(doctest_main PROPERTIES
|
||||
COMPILE_DEFINITIONS "$<$<CXX_COMPILER_ID:MSVC>:_SCL_SECURE_NO_WARNINGS>"
|
||||
COMPILE_OPTIONS "$<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>"
|
||||
)
|
||||
if (${CMAKE_VERSION} VERSION_LESS "3.8.0")
|
||||
target_compile_features(doctest_main PUBLIC cxx_range_for)
|
||||
else()
|
||||
target_compile_features(doctest_main PUBLIC cxx_std_11)
|
||||
endif()
|
||||
target_include_directories(doctest_main PRIVATE "thirdparty/doctest")
|
||||
|
||||
# https://stackoverflow.com/questions/2368811/how-to-set-warning-level-in-cmake
|
||||
if(MSVC)
|
||||
# Force to always compile with W4
|
||||
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
|
||||
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
||||
endif()
|
||||
|
||||
# Disable warning C4566: character represented by universal-character-name '\uFF01' cannot be represented in the current code page (1252)
|
||||
# Disable warning C4996: 'nlohmann::basic_json<std::map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>::operator <<': was declared deprecated
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4566 /wd4996")
|
||||
|
||||
# https://github.com/nlohmann/json/issues/1114
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj")
|
||||
endif()
|
||||
|
||||
#############################################################################
|
||||
# one executable for each unit test file
|
||||
#############################################################################
|
||||
|
||||
set(files
|
||||
src/unit-algorithms.cpp
|
||||
src/unit-allocator.cpp
|
||||
src/unit-alt-string.cpp
|
||||
src/unit-assert_macro.cpp
|
||||
src/unit-bson.cpp
|
||||
src/unit-capacity.cpp
|
||||
src/unit-cbor.cpp
|
||||
src/unit-class_const_iterator.cpp
|
||||
src/unit-class_iterator.cpp
|
||||
src/unit-class_lexer.cpp
|
||||
src/unit-class_parser.cpp
|
||||
src/unit-comparison.cpp
|
||||
src/unit-concepts.cpp
|
||||
src/unit-constructor1.cpp
|
||||
src/unit-constructor2.cpp
|
||||
src/unit-convenience.cpp
|
||||
src/unit-conversions.cpp
|
||||
src/unit-deserialization.cpp
|
||||
src/unit-diagnostics.cpp
|
||||
src/unit-element_access1.cpp
|
||||
src/unit-element_access2.cpp
|
||||
src/unit-hash.cpp
|
||||
src/unit-inspection.cpp
|
||||
src/unit-items.cpp
|
||||
src/unit-iterators1.cpp
|
||||
src/unit-iterators2.cpp
|
||||
src/unit-json_patch.cpp
|
||||
src/unit-json_pointer.cpp
|
||||
src/unit-large_json.cpp
|
||||
src/unit-merge_patch.cpp
|
||||
src/unit-meta.cpp
|
||||
src/unit-modifiers.cpp
|
||||
src/unit-msgpack.cpp
|
||||
src/unit-noexcept.cpp
|
||||
src/unit-ordered_json.cpp
|
||||
src/unit-ordered_map.cpp
|
||||
src/unit-pointer_access.cpp
|
||||
src/unit-readme.cpp
|
||||
src/unit-reference_access.cpp
|
||||
src/unit-regression1.cpp
|
||||
src/unit-regression2.cpp
|
||||
src/unit-serialization.cpp
|
||||
src/unit-testsuites.cpp
|
||||
src/unit-to_chars.cpp
|
||||
src/unit-ubjson.cpp
|
||||
src/unit-udt.cpp
|
||||
src/unit-udt_macro.cpp
|
||||
src/unit-unicode.cpp
|
||||
src/unit-user_defined_input.cpp
|
||||
src/unit-wstring.cpp)
|
||||
|
||||
foreach(file ${files})
|
||||
get_filename_component(file_basename ${file} NAME_WE)
|
||||
string(REGEX REPLACE "unit-([^$]+)" "test-\\1" testcase ${file_basename})
|
||||
|
||||
add_executable(${testcase} $<TARGET_OBJECTS:doctest_main> ${file})
|
||||
target_compile_definitions(${testcase} PRIVATE DOCTEST_CONFIG_SUPER_FAST_ASSERTS)
|
||||
target_compile_options(${testcase} PRIVATE
|
||||
$<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>
|
||||
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>
|
||||
$<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
|
||||
)
|
||||
target_include_directories(${testcase} PRIVATE ${CMAKE_BINARY_DIR}/include thirdparty/doctest thirdparty/fifo_map)
|
||||
target_link_libraries(${testcase} PRIVATE ${NLOHMANN_JSON_TARGET_NAME})
|
||||
|
||||
if (JSON_Coverage)
|
||||
target_compile_options(${testcase} PRIVATE --coverage)
|
||||
target_link_libraries(${testcase} PRIVATE --coverage)
|
||||
endif()
|
||||
|
||||
add_test(NAME "${testcase}"
|
||||
COMMAND ${testcase} ${DOCTEST_TEST_FILTER} --no-skip
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
set_tests_properties("${testcase}" PROPERTIES LABELS "all" FIXTURES_REQUIRED TEST_DATA)
|
||||
|
||||
if(JSON_Valgrind)
|
||||
add_test(NAME "${testcase}_valgrind"
|
||||
COMMAND ${memcheck_command} ${CMAKE_CURRENT_BINARY_DIR}/${testcase} ${DOCTEST_TEST_FILTER}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
set_tests_properties("${testcase}_valgrind" PROPERTIES LABELS "valgrind")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
add_executable(json_unit EXCLUDE_FROM_ALL $<TARGET_OBJECTS:doctest_main> ${files})
|
||||
target_compile_definitions(json_unit PRIVATE DOCTEST_CONFIG_SUPER_FAST_ASSERTS)
|
||||
target_compile_options(json_unit PRIVATE
|
||||
$<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>
|
||||
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>
|
||||
$<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
|
||||
)
|
||||
target_include_directories(json_unit PRIVATE ${CMAKE_BINARY_DIR}/include thirdparty/doctest thirdparty/fifo_map)
|
||||
target_link_libraries(json_unit ${NLOHMANN_JSON_TARGET_NAME})
|
||||
add_dependencies(json_unit download_test_data)
|
||||
|
||||
#############################################################################
|
||||
# Test the generated build configs
|
||||
#############################################################################
|
||||
|
||||
add_subdirectory(cmake_import)
|
||||
add_subdirectory(cmake_import_minver)
|
||||
add_subdirectory(cmake_add_subdirectory)
|
||||
add_subdirectory(cmake_fetch_content)
|
||||
add_subdirectory(cmake_target_include_directories)
|
||||
29
vendor/json/test/Makefile
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
##############################################################################
|
||||
# OSS-Fuzz
|
||||
##############################################################################
|
||||
|
||||
# The following targets realize the integration to OSS-Fuzz.
|
||||
# See <https://github.com/google/oss-fuzz/blob/master/projects/json/build.sh> for more information.
|
||||
|
||||
# additional flags
|
||||
CXXFLAGS += -std=c++11
|
||||
CPPFLAGS += -I ../single_include
|
||||
|
||||
FUZZER_ENGINE = src/fuzzer-driver_afl.cpp
|
||||
FUZZERS = parse_afl_fuzzer parse_bson_fuzzer parse_cbor_fuzzer parse_msgpack_fuzzer parse_ubjson_fuzzer
|
||||
fuzzers: $(FUZZERS)
|
||||
|
||||
parse_afl_fuzzer:
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-parse_json.cpp -o $@
|
||||
|
||||
parse_bson_fuzzer:
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-parse_bson.cpp -o $@
|
||||
|
||||
parse_cbor_fuzzer:
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-parse_cbor.cpp -o $@
|
||||
|
||||
parse_msgpack_fuzzer:
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-parse_msgpack.cpp -o $@
|
||||
|
||||
parse_ubjson_fuzzer:
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(FUZZER_ENGINE) src/fuzzer-parse_ubjson.cpp -o $@
|
||||
18
vendor/json/test/cmake_add_subdirectory/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
add_test(NAME cmake_add_subdirectory_configure
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-G "${CMAKE_GENERATOR}"
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-Dnlohmann_json_source=${PROJECT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/project
|
||||
)
|
||||
add_test(NAME cmake_add_subdirectory_build
|
||||
COMMAND ${CMAKE_COMMAND} --build .
|
||||
)
|
||||
set_tests_properties(cmake_add_subdirectory_configure PROPERTIES
|
||||
FIXTURES_SETUP cmake_add_subdirectory
|
||||
LABELS not_reproducible
|
||||
)
|
||||
set_tests_properties(cmake_add_subdirectory_build PROPERTIES
|
||||
FIXTURES_REQUIRED cmake_add_subdirectory
|
||||
LABELS not_reproducible
|
||||
)
|
||||
20
vendor/json/test/cmake_add_subdirectory/project/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
|
||||
project(DummyImport CXX)
|
||||
|
||||
set(JSON_BuildTests OFF CACHE INTERNAL "")
|
||||
add_subdirectory(${nlohmann_json_source}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/nlohmann_json)
|
||||
|
||||
add_executable(with_namespace_target main.cpp)
|
||||
target_link_libraries(with_namespace_target nlohmann_json::nlohmann_json)
|
||||
|
||||
add_executable(without_namespace_target main.cpp)
|
||||
target_link_libraries(without_namespace_target nlohmann_json)
|
||||
|
||||
if(NOT MSVC)
|
||||
add_executable(without_exceptions main.cpp)
|
||||
target_link_libraries(without_exceptions nlohmann_json::nlohmann_json)
|
||||
target_compile_definitions(without_exceptions PRIVATE JSON_NOEXCEPTION)
|
||||
target_compile_options(without_exceptions PRIVATE -fno-exceptions)
|
||||
endif()
|
||||
8
vendor/json/test/cmake_add_subdirectory/project/main.cpp
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
nlohmann::json j;
|
||||
|
||||
return 0;
|
||||
}
|
||||
20
vendor/json/test/cmake_fetch_content/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
if (${CMAKE_VERSION} VERSION_GREATER "3.11.0")
|
||||
add_test(NAME cmake_fetch_content_configure
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-G "${CMAKE_GENERATOR}"
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-Dnlohmann_json_source=${PROJECT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/project
|
||||
)
|
||||
add_test(NAME cmake_fetch_content_build
|
||||
COMMAND ${CMAKE_COMMAND} --build .
|
||||
)
|
||||
set_tests_properties(cmake_fetch_content_configure PROPERTIES
|
||||
FIXTURES_SETUP cmake_fetch_content
|
||||
LABELS "git_required;not_reproducible"
|
||||
)
|
||||
set_tests_properties(cmake_fetch_content_build PROPERTIES
|
||||
FIXTURES_REQUIRED cmake_fetch_content
|
||||
LABELS "git_required;not_reproducible"
|
||||
)
|
||||
endif()
|
||||
20
vendor/json/test/cmake_fetch_content/project/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.11)
|
||||
|
||||
project(DummyImport CXX)
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
get_filename_component(GIT_REPOSITORY_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../.. ABSOLUTE)
|
||||
FetchContent_Declare(json GIT_REPOSITORY ${GIT_REPOSITORY_DIRECTORY} GIT_TAG HEAD)
|
||||
|
||||
FetchContent_GetProperties(json)
|
||||
if(NOT json_POPULATED)
|
||||
FetchContent_Populate(json)
|
||||
add_subdirectory(${json_SOURCE_DIR} ${json_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
add_executable(with_namespace_target main.cpp)
|
||||
target_link_libraries(with_namespace_target nlohmann_json::nlohmann_json)
|
||||
|
||||
add_executable(without_namespace_target main.cpp)
|
||||
target_link_libraries(without_namespace_target nlohmann_json)
|
||||
8
vendor/json/test/cmake_fetch_content/project/main.cpp
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
nlohmann::json j;
|
||||
|
||||
return 0;
|
||||
}
|
||||
19
vendor/json/test/cmake_import/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
add_test(NAME cmake_import_configure
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-G "${CMAKE_GENERATOR}"
|
||||
-A "${CMAKE_GENERATOR_PLATFORM}"
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-Dnlohmann_json_DIR=${PROJECT_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/project
|
||||
)
|
||||
add_test(NAME cmake_import_build
|
||||
COMMAND ${CMAKE_COMMAND} --build .
|
||||
)
|
||||
set_tests_properties(cmake_import_configure PROPERTIES
|
||||
FIXTURES_SETUP cmake_import
|
||||
LABELS not_reproducible
|
||||
)
|
||||
set_tests_properties(cmake_import_build PROPERTIES
|
||||
FIXTURES_REQUIRED cmake_import
|
||||
LABELS not_reproducible
|
||||
)
|
||||
12
vendor/json/test/cmake_import/project/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
|
||||
project(DummyImport CXX)
|
||||
|
||||
find_package(nlohmann_json REQUIRED)
|
||||
|
||||
add_executable(with_namespace_target main.cpp)
|
||||
target_link_libraries(with_namespace_target nlohmann_json::nlohmann_json)
|
||||
|
||||
add_executable(without_namespace_target main.cpp)
|
||||
target_link_libraries(without_namespace_target nlohmann_json)
|
||||
|
||||
8
vendor/json/test/cmake_import/project/main.cpp
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
nlohmann::json j;
|
||||
|
||||
return 0;
|
||||
}
|
||||
19
vendor/json/test/cmake_import_minver/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
add_test(NAME cmake_import_minver_configure
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-G "${CMAKE_GENERATOR}"
|
||||
-A "${CMAKE_GENERATOR_PLATFORM}"
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-Dnlohmann_json_DIR=${PROJECT_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/project
|
||||
)
|
||||
add_test(NAME cmake_import_minver_build
|
||||
COMMAND ${CMAKE_COMMAND} --build .
|
||||
)
|
||||
set_tests_properties(cmake_import_minver_configure PROPERTIES
|
||||
FIXTURES_SETUP cmake_import_minver
|
||||
LABELS not_reproducible
|
||||
)
|
||||
set_tests_properties(cmake_import_minver_build PROPERTIES
|
||||
FIXTURES_REQUIRED cmake_import_minver
|
||||
LABELS not_reproducible
|
||||
)
|
||||
8
vendor/json/test/cmake_import_minver/project/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
|
||||
project(DummyImportMinVer CXX)
|
||||
|
||||
find_package(nlohmann_json 3.2.0 REQUIRED)
|
||||
|
||||
add_executable(with_namespace_target main.cpp)
|
||||
target_link_libraries(with_namespace_target nlohmann_json::nlohmann_json)
|
||||
8
vendor/json/test/cmake_import_minver/project/main.cpp
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
nlohmann::json j;
|
||||
|
||||
return 0;
|
||||
}
|
||||
18
vendor/json/test/cmake_target_include_directories/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
add_test(NAME cmake_target_include_directories_configure
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-G "${CMAKE_GENERATOR}"
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-Dnlohmann_json_source=${PROJECT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/project
|
||||
)
|
||||
add_test(NAME cmake_target_include_directories_build
|
||||
COMMAND ${CMAKE_COMMAND} --build .
|
||||
)
|
||||
set_tests_properties(cmake_target_include_directories_configure PROPERTIES
|
||||
FIXTURES_SETUP cmake_target_include_directories
|
||||
LABELS not_reproducible
|
||||
)
|
||||
set_tests_properties(cmake_target_include_directories_build PROPERTIES
|
||||
FIXTURES_REQUIRED cmake_target_include_directories
|
||||
LABELS not_reproducible
|
||||
)
|
||||
3
vendor/json/test/cmake_target_include_directories/project/Bar.cpp
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#include "Bar.hpp"
|
||||
|
||||
class Bar;
|
||||
4
vendor/json/test/cmake_target_include_directories/project/Bar.hpp
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "Foo.hpp"
|
||||
|
||||
class Bar : public Foo{};
|
||||
21
vendor/json/test/cmake_target_include_directories/project/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
|
||||
project(DummyImport CXX)
|
||||
|
||||
add_executable(with_private_target main.cpp)
|
||||
target_include_directories(with_private_target PRIVATE ${nlohmann_json_source}/include)
|
||||
set_target_properties(with_private_target PROPERTIES CXX_STANDARD 11)
|
||||
|
||||
add_executable(with_private_system_target main.cpp)
|
||||
target_include_directories(with_private_system_target PRIVATE SYSTEM ${nlohmann_json_source}/include)
|
||||
set_target_properties(with_private_system_target PROPERTIES CXX_STANDARD 11)
|
||||
|
||||
# regression from https://github.com/nlohmann/json/discussions/2281
|
||||
add_library(Foo STATIC Foo.cpp Bar.cpp)
|
||||
target_include_directories(Foo PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${nlohmann_json_source}/include)
|
||||
set_target_properties(Foo PROPERTIES CXX_STANDARD 11)
|
||||
|
||||
add_library(Bar STATIC Bar.cpp)
|
||||
target_link_libraries(Bar PRIVATE Foo)
|
||||
target_include_directories(Bar PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${nlohmann_json_source}/include)
|
||||
set_target_properties(Bar PROPERTIES CXX_STANDARD 11)
|
||||
3
vendor/json/test/cmake_target_include_directories/project/Foo.cpp
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#include "Foo.hpp"
|
||||
|
||||
class Foo;
|
||||
4
vendor/json/test/cmake_target_include_directories/project/Foo.hpp
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
class Foo{};
|
||||
8
vendor/json/test/cmake_target_include_directories/project/main.cpp
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
nlohmann::json j;
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
vendor/json/test/reports/2016-08-29-fuzz/exec_speed.png
vendored
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
vendor/json/test/reports/2016-08-29-fuzz/fuzz.tiff
vendored
Normal file
BIN
vendor/json/test/reports/2016-08-29-fuzz/high_freq.png
vendored
Normal file
|
After Width: | Height: | Size: 26 KiB |
10
vendor/json/test/reports/2016-08-29-fuzz/index.html
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<table style="font-family: 'Trebuchet MS', 'Tahoma', 'Arial', 'Helvetica'">
|
||||
<tr><td style="width: 18ex"><b>Banner:</b></td><td>fuzz</td></tr>
|
||||
<tr><td><b>Directory:</b></td><td>fuzz-testing/out</td></tr>
|
||||
<tr><td><b>Generated on:</b></td><td>Mo 29 Aug 2016 22:14:22 CEST</td></tr>
|
||||
</table>
|
||||
<p>
|
||||
<img src="high_freq.png" width=1000 height=300><p>
|
||||
<img src="low_freq.png" width=1000 height=200><p>
|
||||
<img src="exec_speed.png" width=1000 height=200>
|
||||
|
||||
BIN
vendor/json/test/reports/2016-08-29-fuzz/low_freq.png
vendored
Normal file
|
After Width: | Height: | Size: 12 KiB |
31
vendor/json/test/reports/2016-09-09-nativejson_benchmark/README.md
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
Results of the latest benchmark from <https://github.com/miloyip/nativejson-benchmark>.
|
||||
|
||||
See <https://github.com/nlohmann/json/issues/307> for discussion.
|
||||
|
||||
Original post at 2016-09-09 to <json@yahoogroups.com>:
|
||||
|
||||
> Hi,
|
||||
>
|
||||
> This benchmark evaluated conformance, parse/stringify speed/memory, and
|
||||
> code size. It can also be viewed as a long list of open source C/C++ JSON
|
||||
> libraries.
|
||||
>
|
||||
> You can run the benchmark on your own machine by checkout this project.
|
||||
>
|
||||
> https://github.com/miloyip/nativejson-benchmark
|
||||
>
|
||||
> You can also view some sample results here:
|
||||
>
|
||||
> https://rawgit.com/miloyip/nativejson-benchmark/master/sample/conformance.html
|
||||
> https://rawgit.com/miloyip/nativejson-benchmark/master/sample/performance_Corei7-4980HQ@2.80GHz_mac64_clang7.0.html
|
||||
>
|
||||
> If you make a new library, you may use this for testing conformance and
|
||||
> performance. Afterwards, please submit a pull request.
|
||||
>
|
||||
> Enjoy!
|
||||
>
|
||||
> --
|
||||
> Milo Yip
|
||||
>
|
||||
> https://github.com/miloyip/
|
||||
> http://twitter.com/miloyip/
|
||||
670
vendor/json/test/reports/2016-09-09-nativejson_benchmark/conformance_Nlohmann (C++11).md
vendored
Normal file
@@ -0,0 +1,670 @@
|
||||
|
||||
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="">
|
||||
<head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# object: http://ogp.me/ns/object# article: http://ogp.me/ns/article# profile: http://ogp.me/ns/profile#">
|
||||
<meta charset='utf-8'>
|
||||
|
||||
|
||||
<link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/frameworks-3a71f36dec04358c4f2f42280fb2cf5c38856f935a3f609eab0a1ae31b1d635a.css" media="all" rel="stylesheet" />
|
||||
<link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/github-5c885e880e980dc7f119393287b84906d930ccaff83f6bff8ae2c086b87ca4d8.css" media="all" rel="stylesheet" />
|
||||
|
||||
|
||||
<link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/site-4ef7bbe907458c89cb1f7f5c5e6c4cd87e03acf66b1817325e644920d2a83330.css" media="all" rel="stylesheet" />
|
||||
|
||||
|
||||
<link as="script" href="https://assets-cdn.github.com/assets/frameworks-88471af1fec40ff9418efbe2ddd15b6896af8d772f8179004c254dffc25ea490.js" rel="preload" />
|
||||
|
||||
<link as="script" href="https://assets-cdn.github.com/assets/github-e18e11a943ff2eb9394c72d4ec8b76592c454915b5839ae177d422777a046e29.js" rel="preload" />
|
||||
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta http-equiv="Content-Language" content="en">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
|
||||
<title>nativejson-benchmark/conformance_Nlohmann (C++11).md at master · miloyip/nativejson-benchmark · GitHub</title>
|
||||
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub">
|
||||
<link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub">
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png">
|
||||
<meta property="fb:app_id" content="1401488693436528">
|
||||
|
||||
<meta content="https://avatars2.githubusercontent.com/u/1195774?v=3&s=400" name="twitter:image:src" /><meta content="@github" name="twitter:site" /><meta content="summary" name="twitter:card" /><meta content="miloyip/nativejson-benchmark" name="twitter:title" /><meta content="nativejson-benchmark - C/C++ JSON parser/generator benchmark" name="twitter:description" />
|
||||
<meta content="https://avatars2.githubusercontent.com/u/1195774?v=3&s=400" property="og:image" /><meta content="GitHub" property="og:site_name" /><meta content="object" property="og:type" /><meta content="miloyip/nativejson-benchmark" property="og:title" /><meta content="https://github.com/miloyip/nativejson-benchmark" property="og:url" /><meta content="nativejson-benchmark - C/C++ JSON parser/generator benchmark" property="og:description" />
|
||||
<meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats">
|
||||
<meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors">
|
||||
<link rel="assets" href="https://assets-cdn.github.com/">
|
||||
|
||||
<meta name="pjax-timeout" content="1000">
|
||||
|
||||
<meta name="request-id" content="D4563DA7:75ED:525C921:57D6FEBB" data-pjax-transient>
|
||||
|
||||
<meta name="msapplication-TileImage" content="/windows-tile.png">
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<meta name="selected-link" value="repo_source" data-pjax-transient>
|
||||
|
||||
<meta name="google-site-verification" content="KT5gs8h0wvaagLKAVWq8bbeNwnZZK1r1XQysX3xurLU">
|
||||
<meta name="google-site-verification" content="ZzhVyEFwb7w3e0-uOTltm8Jsck2F5StVihD0exw2fsA">
|
||||
<meta name="google-analytics" content="UA-3769691-2">
|
||||
|
||||
<meta content="collector.githubapp.com" name="octolytics-host" /><meta content="github" name="octolytics-app-id" /><meta content="D4563DA7:75ED:525C921:57D6FEBB" name="octolytics-dimension-request_id" />
|
||||
<meta content="/<user-name>/<repo-name>/blob/show" data-pjax-transient="true" name="analytics-location" />
|
||||
|
||||
|
||||
|
||||
<meta class="js-ga-set" name="dimension1" content="Logged Out">
|
||||
|
||||
|
||||
|
||||
<meta name="hostname" content="github.com">
|
||||
<meta name="user-login" content="">
|
||||
|
||||
<meta name="expected-hostname" content="github.com">
|
||||
<meta name="js-proxy-site-detection-payload" content="N2RkMmY1ZjE1MTA4MzRhYTA5NDNkMjliNDU3OTA3ZTdlMGNmNDZjN2QyODBiZjM3MmYzMjFjNzY1ZjIwNjY4NHx7InJlbW90ZV9hZGRyZXNzIjoiMjEyLjg2LjYxLjE2NyIsInJlcXVlc3RfaWQiOiJENDU2M0RBNzo3NUVEOjUyNUM5MjE6NTdENkZFQkIiLCJ0aW1lc3RhbXAiOjE0NzM3MDc3MDh9">
|
||||
|
||||
|
||||
<link rel="mask-icon" href="https://assets-cdn.github.com/pinned-octocat.svg" color="#4078c0">
|
||||
<link rel="icon" type="image/x-icon" href="https://assets-cdn.github.com/favicon.ico">
|
||||
|
||||
<meta name="html-safe-nonce" content="deea0f406df2fb95709865c5ee80a255d8c47fa9">
|
||||
<meta content="736eea9d74cf34fe850d2180e8a5f0a1cc7bc0be" name="form-nonce" />
|
||||
|
||||
<meta http-equiv="x-pjax-version" content="f302977937abe3fe1c9a4d4bed913565">
|
||||
|
||||
|
||||
|
||||
<meta name="description" content="nativejson-benchmark - C/C++ JSON parser/generator benchmark">
|
||||
<meta name="go-import" content="github.com/miloyip/nativejson-benchmark git https://github.com/miloyip/nativejson-benchmark.git">
|
||||
|
||||
<meta content="1195774" name="octolytics-dimension-user_id" /><meta content="miloyip" name="octolytics-dimension-user_login" /><meta content="22976798" name="octolytics-dimension-repository_id" /><meta content="miloyip/nativejson-benchmark" name="octolytics-dimension-repository_nwo" /><meta content="true" name="octolytics-dimension-repository_public" /><meta content="false" name="octolytics-dimension-repository_is_fork" /><meta content="22976798" name="octolytics-dimension-repository_network_root_id" /><meta content="miloyip/nativejson-benchmark" name="octolytics-dimension-repository_network_root_nwo" />
|
||||
<link href="https://github.com/miloyip/nativejson-benchmark/commits/master.atom" rel="alternate" title="Recent Commits to nativejson-benchmark:master" type="application/atom+xml">
|
||||
|
||||
|
||||
<link rel="canonical" href="https://github.com/miloyip/nativejson-benchmark/blob/master/sample/conformance_Nlohmann%20(C%2B%2B11).md" data-pjax-transient>
|
||||
</head>
|
||||
|
||||
|
||||
<body class="logged-out env-production vis-public page-blob">
|
||||
<div id="js-pjax-loader-bar" class="pjax-loader-bar"><div class="progress"></div></div>
|
||||
<a href="#start-of-content" tabindex="1" class="accessibility-aid js-skip-to-content">Skip to content</a>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<header class="site-header js-details-container" role="banner">
|
||||
<div class="container-responsive">
|
||||
<a class="header-logo-invertocat" href="https://github.com/" aria-label="Homepage" data-ga-click="(Logged out) Header, go to homepage, icon:logo-wordmark">
|
||||
<svg aria-hidden="true" class="octicon octicon-mark-github" height="32" version="1.1" viewBox="0 0 16 16" width="32"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg>
|
||||
</a>
|
||||
|
||||
<button class="btn-link float-right site-header-toggle js-details-target" type="button" aria-label="Toggle navigation">
|
||||
<svg aria-hidden="true" class="octicon octicon-three-bars" height="24" version="1.1" viewBox="0 0 12 16" width="18"><path d="M11.41 9H.59C0 9 0 8.59 0 8c0-.59 0-1 .59-1H11.4c.59 0 .59.41.59 1 0 .59 0 1-.59 1h.01zm0-4H.59C0 5 0 4.59 0 4c0-.59 0-1 .59-1H11.4c.59 0 .59.41.59 1 0 .59 0 1-.59 1h.01zM.59 11H11.4c.59 0 .59.41.59 1 0 .59 0 1-.59 1H.59C0 13 0 12.59 0 12c0-.59 0-1 .59-1z"></path></svg>
|
||||
</button>
|
||||
|
||||
<div class="site-header-menu">
|
||||
<nav class="site-header-nav site-header-nav-main">
|
||||
<a href="/personal" class="js-selected-navigation-item nav-item nav-item-personal" data-ga-click="Header, click, Nav menu - item:personal" data-selected-links="/personal /personal">
|
||||
Personal
|
||||
</a> <a href="/open-source" class="js-selected-navigation-item nav-item nav-item-opensource" data-ga-click="Header, click, Nav menu - item:opensource" data-selected-links="/open-source /open-source">
|
||||
Open source
|
||||
</a> <a href="/business" class="js-selected-navigation-item nav-item nav-item-business" data-ga-click="Header, click, Nav menu - item:business" data-selected-links="/business /business/partners /business/features /business/customers /business">
|
||||
Business
|
||||
</a> <a href="/explore" class="js-selected-navigation-item nav-item nav-item-explore" data-ga-click="Header, click, Nav menu - item:explore" data-selected-links="/explore /trending /trending/developers /integrations /integrations/feature/code /integrations/feature/collaborate /integrations/feature/ship /explore">
|
||||
Explore
|
||||
</a> </nav>
|
||||
|
||||
<div class="site-header-actions">
|
||||
<a class="btn btn-primary site-header-actions-btn" href="/join?source=header-repo" data-ga-click="(Logged out) Header, clicked Sign up, text:sign-up">Sign up</a>
|
||||
<a class="btn site-header-actions-btn mr-2" href="/login?return_to=%2Fmiloyip%2Fnativejson-benchmark%2Fblob%2Fmaster%2Fsample%2Fconformance_Nlohmann%2520%28C%252B%252B11%29.md" data-ga-click="(Logged out) Header, clicked Sign in, text:sign-in">Sign in</a>
|
||||
</div>
|
||||
|
||||
<nav class="site-header-nav site-header-nav-secondary">
|
||||
<a class="nav-item" href="/pricing">Pricing</a>
|
||||
<a class="nav-item" href="/blog">Blog</a>
|
||||
<a class="nav-item" href="https://help.github.com">Support</a>
|
||||
<a class="nav-item header-search-link" href="https://github.com/search">Search GitHub</a>
|
||||
<div class="header-search scoped-search site-scoped-search js-site-search" role="search">
|
||||
<!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/miloyip/nativejson-benchmark/search" class="js-site-search-form" data-scoped-search-url="/miloyip/nativejson-benchmark/search" data-unscoped-search-url="/search" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /></div>
|
||||
<label class="form-control header-search-wrapper js-chromeless-input-container">
|
||||
<div class="header-search-scope">This repository</div>
|
||||
<input type="text"
|
||||
class="form-control header-search-input js-site-search-focus js-site-search-field is-clearable"
|
||||
data-hotkey="s"
|
||||
name="q"
|
||||
placeholder="Search"
|
||||
aria-label="Search this repository"
|
||||
data-unscoped-placeholder="Search GitHub"
|
||||
data-scoped-placeholder="Search"
|
||||
autocapitalize="off">
|
||||
</label>
|
||||
</form></div>
|
||||
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
|
||||
<div id="start-of-content" class="accessibility-aid"></div>
|
||||
|
||||
<div id="js-flash-container">
|
||||
</div>
|
||||
|
||||
|
||||
<div role="main">
|
||||
<div itemscope itemtype="http://schema.org/SoftwareSourceCode">
|
||||
<div id="js-repo-pjax-container" data-pjax-container>
|
||||
|
||||
<div class="pagehead repohead instapaper_ignore readability-menu experiment-repo-nav">
|
||||
<div class="container repohead-details-container">
|
||||
|
||||
|
||||
|
||||
<ul class="pagehead-actions">
|
||||
|
||||
<li>
|
||||
<a href="/login?return_to=%2Fmiloyip%2Fnativejson-benchmark"
|
||||
class="btn btn-sm btn-with-count tooltipped tooltipped-n"
|
||||
aria-label="You must be signed in to watch a repository" rel="nofollow">
|
||||
<svg aria-hidden="true" class="octicon octicon-eye" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z"></path></svg>
|
||||
Watch
|
||||
</a>
|
||||
<a class="social-count" href="/miloyip/nativejson-benchmark/watchers"
|
||||
aria-label="40 users are watching this repository">
|
||||
40
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="/login?return_to=%2Fmiloyip%2Fnativejson-benchmark"
|
||||
class="btn btn-sm btn-with-count tooltipped tooltipped-n"
|
||||
aria-label="You must be signed in to star a repository" rel="nofollow">
|
||||
<svg aria-hidden="true" class="octicon octicon-star" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path d="M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74z"></path></svg>
|
||||
Star
|
||||
</a>
|
||||
|
||||
<a class="social-count js-social-count" href="/miloyip/nativejson-benchmark/stargazers"
|
||||
aria-label="352 users starred this repository">
|
||||
352
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="/login?return_to=%2Fmiloyip%2Fnativejson-benchmark"
|
||||
class="btn btn-sm btn-with-count tooltipped tooltipped-n"
|
||||
aria-label="You must be signed in to fork a repository" rel="nofollow">
|
||||
<svg aria-hidden="true" class="octicon octicon-repo-forked" height="16" version="1.1" viewBox="0 0 10 16" width="10"><path d="M8 1a1.993 1.993 0 0 0-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V6.5l3 3v1.78A1.993 1.993 0 0 0 5 15a1.993 1.993 0 0 0 1-3.72V9.5l3-3V4.72A1.993 1.993 0 0 0 8 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"></path></svg>
|
||||
Fork
|
||||
</a>
|
||||
|
||||
<a href="/miloyip/nativejson-benchmark/network" class="social-count"
|
||||
aria-label="59 users are forked this repository">
|
||||
59
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h1 class="public ">
|
||||
<svg aria-hidden="true" class="octicon octicon-repo" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M4 9H3V8h1v1zm0-3H3v1h1V6zm0-2H3v1h1V4zm0-2H3v1h1V2zm8-1v12c0 .55-.45 1-1 1H6v2l-1.5-1.5L3 16v-2H1c-.55 0-1-.45-1-1V1c0-.55.45-1 1-1h10c.55 0 1 .45 1 1zm-1 10H1v2h2v-1h3v1h5v-2zm0-10H2v9h9V1z"></path></svg>
|
||||
<span class="author" itemprop="author"><a href="/miloyip" class="url fn" rel="author">miloyip</a></span><!--
|
||||
--><span class="path-divider">/</span><!--
|
||||
--><strong itemprop="name"><a href="/miloyip/nativejson-benchmark" data-pjax="#js-repo-pjax-container">nativejson-benchmark</a></strong>
|
||||
|
||||
</h1>
|
||||
|
||||
</div>
|
||||
<div class="container">
|
||||
|
||||
<nav class="reponav js-repo-nav js-sidenav-container-pjax"
|
||||
itemscope
|
||||
itemtype="http://schema.org/BreadcrumbList"
|
||||
role="navigation"
|
||||
data-pjax="#js-repo-pjax-container">
|
||||
|
||||
<span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
|
||||
<a href="/miloyip/nativejson-benchmark" aria-selected="true" class="js-selected-navigation-item selected reponav-item" data-hotkey="g c" data-selected-links="repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches /miloyip/nativejson-benchmark" itemprop="url">
|
||||
<svg aria-hidden="true" class="octicon octicon-code" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path d="M9.5 3L8 4.5 11.5 8 8 11.5 9.5 13 14 8 9.5 3zm-5 0L0 8l4.5 5L6 11.5 2.5 8 6 4.5 4.5 3z"></path></svg>
|
||||
<span itemprop="name">Code</span>
|
||||
<meta itemprop="position" content="1">
|
||||
</a> </span>
|
||||
|
||||
<span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
|
||||
<a href="/miloyip/nativejson-benchmark/issues" class="js-selected-navigation-item reponav-item" data-hotkey="g i" data-selected-links="repo_issues repo_labels repo_milestones /miloyip/nativejson-benchmark/issues" itemprop="url">
|
||||
<svg aria-hidden="true" class="octicon octicon-issue-opened" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg>
|
||||
<span itemprop="name">Issues</span>
|
||||
<span class="counter">8</span>
|
||||
<meta itemprop="position" content="2">
|
||||
</a> </span>
|
||||
|
||||
<span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
|
||||
<a href="/miloyip/nativejson-benchmark/pulls" class="js-selected-navigation-item reponav-item" data-hotkey="g p" data-selected-links="repo_pulls /miloyip/nativejson-benchmark/pulls" itemprop="url">
|
||||
<svg aria-hidden="true" class="octicon octicon-git-pull-request" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M11 11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993 1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98 1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"></path></svg>
|
||||
<span itemprop="name">Pull requests</span>
|
||||
<span class="counter">1</span>
|
||||
<meta itemprop="position" content="3">
|
||||
</a> </span>
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/miloyip/nativejson-benchmark/pulse" class="js-selected-navigation-item reponav-item" data-selected-links="pulse /miloyip/nativejson-benchmark/pulse">
|
||||
<svg aria-hidden="true" class="octicon octicon-pulse" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path d="M11.5 8L8.8 5.4 6.6 8.5 5.5 1.6 2.38 8H0v2h3.6l.9-1.8.9 5.4L9 8.5l1.6 1.5H14V8z"></path></svg>
|
||||
Pulse
|
||||
</a>
|
||||
<a href="/miloyip/nativejson-benchmark/graphs" class="js-selected-navigation-item reponav-item" data-selected-links="repo_graphs repo_contributors /miloyip/nativejson-benchmark/graphs">
|
||||
<svg aria-hidden="true" class="octicon octicon-graph" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4 0H7V3h2v10zm4 0h-2V6h2v7z"></path></svg>
|
||||
Graphs
|
||||
</a>
|
||||
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container new-discussion-timeline experiment-repo-nav">
|
||||
<div class="repository-content">
|
||||
|
||||
|
||||
|
||||
<a href="/miloyip/nativejson-benchmark/blob/95f27ebcf9a96c7ca4cee26467ed5420140090fb/sample/conformance_Nlohmann%20(C%2B%2B11).md" class="d-none js-permalink-shortcut" data-hotkey="y">Permalink</a>
|
||||
|
||||
<!-- blob contrib key: blob_contributors:v21:0bf9e3593dedd91db6c9dc69e13b7f95 -->
|
||||
|
||||
<div class="file-navigation js-zeroclipboard-container">
|
||||
|
||||
<div class="select-menu branch-select-menu js-menu-container js-select-menu float-left">
|
||||
<button class="btn btn-sm select-menu-button js-menu-target css-truncate" data-hotkey="w"
|
||||
|
||||
type="button" aria-label="Switch branches or tags" tabindex="0" aria-haspopup="true">
|
||||
<i>Branch:</i>
|
||||
<span class="js-select-button css-truncate-target">master</span>
|
||||
</button>
|
||||
|
||||
<div class="select-menu-modal-holder js-menu-content js-navigation-container" data-pjax aria-hidden="true">
|
||||
|
||||
<div class="select-menu-modal">
|
||||
<div class="select-menu-header">
|
||||
<svg aria-label="Close" class="octicon octicon-x js-menu-close" height="16" role="img" version="1.1" viewBox="0 0 12 16" width="12"><path d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"></path></svg>
|
||||
<span class="select-menu-title">Switch branches/tags</span>
|
||||
</div>
|
||||
|
||||
<div class="select-menu-filters">
|
||||
<div class="select-menu-text-filter">
|
||||
<input type="text" aria-label="Filter branches/tags" id="context-commitish-filter-field" class="form-control js-filterable-field js-navigation-enable" placeholder="Filter branches/tags">
|
||||
</div>
|
||||
<div class="select-menu-tabs">
|
||||
<ul>
|
||||
<li class="select-menu-tab">
|
||||
<a href="#" data-tab-filter="branches" data-filter-placeholder="Filter branches/tags" class="js-select-menu-tab" role="tab">Branches</a>
|
||||
</li>
|
||||
<li class="select-menu-tab">
|
||||
<a href="#" data-tab-filter="tags" data-filter-placeholder="Find a tag…" class="js-select-menu-tab" role="tab">Tags</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="branches" role="menu">
|
||||
|
||||
<div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring">
|
||||
|
||||
|
||||
<a class="select-menu-item js-navigation-item js-navigation-open "
|
||||
href="/miloyip/nativejson-benchmark/blob/Stixjson/sample/conformance_Nlohmann%20(C++11).md"
|
||||
data-name="Stixjson"
|
||||
data-skip-pjax="true"
|
||||
rel="nofollow">
|
||||
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
|
||||
<span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
|
||||
Stixjson
|
||||
</span>
|
||||
</a>
|
||||
<a class="select-menu-item js-navigation-item js-navigation-open "
|
||||
href="/miloyip/nativejson-benchmark/blob/ccan/sample/conformance_Nlohmann%20(C++11).md"
|
||||
data-name="ccan"
|
||||
data-skip-pjax="true"
|
||||
rel="nofollow">
|
||||
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
|
||||
<span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
|
||||
ccan
|
||||
</span>
|
||||
</a>
|
||||
<a class="select-menu-item js-navigation-item js-navigation-open "
|
||||
href="/miloyip/nativejson-benchmark/blob/jbson/sample/conformance_Nlohmann%20(C++11).md"
|
||||
data-name="jbson"
|
||||
data-skip-pjax="true"
|
||||
rel="nofollow">
|
||||
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
|
||||
<span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
|
||||
jbson
|
||||
</span>
|
||||
</a>
|
||||
<a class="select-menu-item js-navigation-item js-navigation-open "
|
||||
href="/miloyip/nativejson-benchmark/blob/jute/sample/conformance_Nlohmann%20(C++11).md"
|
||||
data-name="jute"
|
||||
data-skip-pjax="true"
|
||||
rel="nofollow">
|
||||
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
|
||||
<span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
|
||||
jute
|
||||
</span>
|
||||
</a>
|
||||
<a class="select-menu-item js-navigation-item js-navigation-open "
|
||||
href="/miloyip/nativejson-benchmark/blob/lastjson/sample/conformance_Nlohmann%20(C++11).md"
|
||||
data-name="lastjson"
|
||||
data-skip-pjax="true"
|
||||
rel="nofollow">
|
||||
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
|
||||
<span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
|
||||
lastjson
|
||||
</span>
|
||||
</a>
|
||||
<a class="select-menu-item js-navigation-item js-navigation-open "
|
||||
href="/miloyip/nativejson-benchmark/blob/libjson/sample/conformance_Nlohmann%20(C++11).md"
|
||||
data-name="libjson"
|
||||
data-skip-pjax="true"
|
||||
rel="nofollow">
|
||||
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
|
||||
<span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
|
||||
libjson
|
||||
</span>
|
||||
</a>
|
||||
<a class="select-menu-item js-navigation-item js-navigation-open selected"
|
||||
href="/miloyip/nativejson-benchmark/blob/master/sample/conformance_Nlohmann%20(C++11).md"
|
||||
data-name="master"
|
||||
data-skip-pjax="true"
|
||||
rel="nofollow">
|
||||
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
|
||||
<span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
|
||||
master
|
||||
</span>
|
||||
</a>
|
||||
<a class="select-menu-item js-navigation-item js-navigation-open "
|
||||
href="/miloyip/nativejson-benchmark/blob/qt/sample/conformance_Nlohmann%20(C++11).md"
|
||||
data-name="qt"
|
||||
data-skip-pjax="true"
|
||||
rel="nofollow">
|
||||
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
|
||||
<span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
|
||||
qt
|
||||
</span>
|
||||
</a>
|
||||
<a class="select-menu-item js-navigation-item js-navigation-open "
|
||||
href="/miloyip/nativejson-benchmark/blob/tunnuz/sample/conformance_Nlohmann%20(C++11).md"
|
||||
data-name="tunnuz"
|
||||
data-skip-pjax="true"
|
||||
rel="nofollow">
|
||||
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
|
||||
<span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
|
||||
tunnuz
|
||||
</span>
|
||||
</a>
|
||||
<a class="select-menu-item js-navigation-item js-navigation-open "
|
||||
href="/miloyip/nativejson-benchmark/blob/ujson/sample/conformance_Nlohmann%20(C++11).md"
|
||||
data-name="ujson"
|
||||
data-skip-pjax="true"
|
||||
rel="nofollow">
|
||||
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
|
||||
<span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
|
||||
ujson
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="select-menu-no-results">Nothing to show</div>
|
||||
</div>
|
||||
|
||||
<div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="tags">
|
||||
<div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring">
|
||||
|
||||
|
||||
<a class="select-menu-item js-navigation-item js-navigation-open "
|
||||
href="/miloyip/nativejson-benchmark/tree/v1.0.0/sample/conformance_Nlohmann%20(C%2B%2B11).md"
|
||||
data-name="v1.0.0"
|
||||
data-skip-pjax="true"
|
||||
rel="nofollow">
|
||||
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
|
||||
<span class="select-menu-item-text css-truncate-target" title="v1.0.0">
|
||||
v1.0.0
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="select-menu-no-results">Nothing to show</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="btn-group float-right">
|
||||
<a href="/miloyip/nativejson-benchmark/find/master"
|
||||
class="js-pjax-capture-input btn btn-sm"
|
||||
data-pjax
|
||||
data-hotkey="t">
|
||||
Find file
|
||||
</a>
|
||||
<button aria-label="Copy file path to clipboard" class="js-zeroclipboard btn btn-sm zeroclipboard-button tooltipped tooltipped-s" data-copied-hint="Copied!" type="button">Copy path</button>
|
||||
</div>
|
||||
<div class="breadcrumb js-zeroclipboard-target">
|
||||
<span class="repo-root js-repo-root"><span class="js-path-segment"><a href="/miloyip/nativejson-benchmark"><span>nativejson-benchmark</span></a></span></span><span class="separator">/</span><span class="js-path-segment"><a href="/miloyip/nativejson-benchmark/tree/master/sample"><span>sample</span></a></span><span class="separator">/</span><strong class="final-path">conformance_Nlohmann (C++11).md</strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="commit-tease">
|
||||
<span class="float-right">
|
||||
<a class="commit-tease-sha" href="/miloyip/nativejson-benchmark/commit/a4a9f10f41c515d6abb0f019ab9f5d021ed4bb9e" data-pjax>
|
||||
a4a9f10
|
||||
</a>
|
||||
<relative-time datetime="2016-09-09T03:15:21Z">Sep 9, 2016</relative-time>
|
||||
</span>
|
||||
<div>
|
||||
<img alt="@miloyip" class="avatar" height="20" src="https://avatars3.githubusercontent.com/u/1195774?v=3&s=40" width="20" />
|
||||
<a href="/miloyip" class="user-mention" rel="author">miloyip</a>
|
||||
<a href="/miloyip/nativejson-benchmark/commit/a4a9f10f41c515d6abb0f019ab9f5d021ed4bb9e" class="message" data-pjax="true" title="Update sample result for 41 libraries
|
||||
|
||||
Fixed #43">Update sample result for 41 libraries</a>
|
||||
</div>
|
||||
|
||||
<div class="commit-tease-contributors">
|
||||
<button type="button" class="btn-link muted-link contributors-toggle" data-facebox="#blob_contributors_box">
|
||||
<strong>1</strong>
|
||||
contributor
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="blob_contributors_box" style="display:none">
|
||||
<h2 class="facebox-header" data-facebox-id="facebox-header">Users who have contributed to this file</h2>
|
||||
<ul class="facebox-user-list" data-facebox-id="facebox-description">
|
||||
<li class="facebox-user-list-item">
|
||||
<img alt="@miloyip" height="24" src="https://avatars1.githubusercontent.com/u/1195774?v=3&s=48" width="24" />
|
||||
<a href="/miloyip">miloyip</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="file">
|
||||
<div class="file-header">
|
||||
<div class="file-actions">
|
||||
|
||||
<div class="btn-group">
|
||||
<a href="/miloyip/nativejson-benchmark/raw/master/sample/conformance_Nlohmann%20(C%2B%2B11).md" class="btn btn-sm " id="raw-url">Raw</a>
|
||||
<a href="/miloyip/nativejson-benchmark/blame/master/sample/conformance_Nlohmann%20(C%2B%2B11).md" class="btn btn-sm js-update-url-with-hash">Blame</a>
|
||||
<a href="/miloyip/nativejson-benchmark/commits/master/sample/conformance_Nlohmann%20(C%2B%2B11).md" class="btn btn-sm " rel="nofollow">History</a>
|
||||
</div>
|
||||
|
||||
|
||||
<button type="button" class="btn-octicon disabled tooltipped tooltipped-nw"
|
||||
aria-label="You must be signed in to make or propose changes">
|
||||
<svg aria-hidden="true" class="octicon octicon-pencil" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path d="M0 12v3h3l8-8-3-3-8 8zm3 2H1v-2h1v1h1v1zm10.3-9.3L12 6 9 3l1.3-1.3a.996.996 0 0 1 1.41 0l1.59 1.59c.39.39.39 1.02 0 1.41z"></path></svg>
|
||||
</button>
|
||||
<button type="button" class="btn-octicon btn-octicon-danger disabled tooltipped tooltipped-nw"
|
||||
aria-label="You must be signed in to make or propose changes">
|
||||
<svg aria-hidden="true" class="octicon octicon-trashcan" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M11 2H9c0-.55-.45-1-1-1H5c-.55 0-1 .45-1 1H2c-.55 0-1 .45-1 1v1c0 .55.45 1 1 1v9c0 .55.45 1 1 1h7c.55 0 1-.45 1-1V5c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm-1 12H3V5h1v8h1V5h1v8h1V5h1v8h1V5h1v9zm1-10H2V3h9v1z"></path></svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="file-info">
|
||||
59 lines (37 sloc)
|
||||
<span class="file-info-divider"></span>
|
||||
545 Bytes
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="readme" class="readme blob instapaper_body">
|
||||
<article class="markdown-body entry-content" itemprop="text"><h1><a id="user-content-conformance-of-nlohmann-c11" class="anchor" href="#conformance-of-nlohmann-c11" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Conformance of Nlohmann (C++11)</h1>
|
||||
|
||||
<h2><a id="user-content-1-parse-validation" class="anchor" href="#1-parse-validation" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>1. Parse Validation</h2>
|
||||
|
||||
<p>Summary: 34 of 34 are correct.</p>
|
||||
|
||||
<h2><a id="user-content-2-parse-double" class="anchor" href="#2-parse-double" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>2. Parse Double</h2>
|
||||
|
||||
<p>Summary: 66 of 66 are correct.</p>
|
||||
|
||||
<h2><a id="user-content-3-parse-string" class="anchor" href="#3-parse-string" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>3. Parse String</h2>
|
||||
|
||||
<p>Summary: 9 of 9 are correct.</p>
|
||||
|
||||
<h2><a id="user-content-4-roundtrip" class="anchor" href="#4-roundtrip" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>4. Roundtrip</h2>
|
||||
|
||||
<ul>
|
||||
<li>Fail:</li>
|
||||
</ul>
|
||||
|
||||
<div class="highlight highlight-source-js"><pre>[<span class="pl-c1">5e-324</span>]</pre></div>
|
||||
|
||||
<div class="highlight highlight-source-js"><pre>[<span class="pl-c1">4.94065645841247e-324</span>]</pre></div>
|
||||
|
||||
<ul>
|
||||
<li>Fail:</li>
|
||||
</ul>
|
||||
|
||||
<div class="highlight highlight-source-js"><pre>[<span class="pl-c1">2.225073858507201e-308</span>]</pre></div>
|
||||
|
||||
<div class="highlight highlight-source-js"><pre>[<span class="pl-c1">2.2250738585072e-308</span>]</pre></div>
|
||||
|
||||
<ul>
|
||||
<li>Fail:</li>
|
||||
</ul>
|
||||
|
||||
<div class="highlight highlight-source-js"><pre>[<span class="pl-c1">2.2250738585072014e-308</span>]</pre></div>
|
||||
|
||||
<div class="highlight highlight-source-js"><pre>[<span class="pl-c1">2.2250738585072e-308</span>]</pre></div>
|
||||
|
||||
<ul>
|
||||
<li>Fail:</li>
|
||||
</ul>
|
||||
|
||||
<div class="highlight highlight-source-js"><pre>[<span class="pl-c1">1.7976931348623157e308</span>]</pre></div>
|
||||
|
||||
<div class="highlight highlight-source-js"><pre>[<span class="pl-c1">1.79769313486232e+308</span>]</pre></div>
|
||||
|
||||
<p>Summary: 23 of 27 are correct.</p>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<button type="button" data-facebox="#jump-to-line" data-facebox-class="linejump" data-hotkey="l" class="d-none">Jump to Line</button>
|
||||
<div id="jump-to-line" style="display:none">
|
||||
<!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="" class="js-jump-to-line-form" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /></div>
|
||||
<input class="form-control linejump-input js-jump-to-line-field" type="text" placeholder="Jump to line…" aria-label="Jump to line" autofocus>
|
||||
<button type="submit" class="btn">Go</button>
|
||||
</form></div>
|
||||
|
||||
</div>
|
||||
<div class="modal-backdrop js-touch-events"></div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="container site-footer-container">
|
||||
<div class="site-footer" role="contentinfo">
|
||||
<ul class="site-footer-links float-right">
|
||||
<li><a href="https://github.com/contact" data-ga-click="Footer, go to contact, text:contact">Contact GitHub</a></li>
|
||||
<li><a href="https://developer.github.com" data-ga-click="Footer, go to api, text:api">API</a></li>
|
||||
<li><a href="https://training.github.com" data-ga-click="Footer, go to training, text:training">Training</a></li>
|
||||
<li><a href="https://shop.github.com" data-ga-click="Footer, go to shop, text:shop">Shop</a></li>
|
||||
<li><a href="https://github.com/blog" data-ga-click="Footer, go to blog, text:blog">Blog</a></li>
|
||||
<li><a href="https://github.com/about" data-ga-click="Footer, go to about, text:about">About</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
<a href="https://github.com" aria-label="Homepage" class="site-footer-mark" title="GitHub">
|
||||
<svg aria-hidden="true" class="octicon octicon-mark-github" height="24" version="1.1" viewBox="0 0 16 16" width="24"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg>
|
||||
</a>
|
||||
<ul class="site-footer-links">
|
||||
<li>© 2016 <span title="0.18611s from github-fe151-cp1-prd.iad.github.net">GitHub</span>, Inc.</li>
|
||||
<li><a href="https://github.com/site/terms" data-ga-click="Footer, go to terms, text:terms">Terms</a></li>
|
||||
<li><a href="https://github.com/site/privacy" data-ga-click="Footer, go to privacy, text:privacy">Privacy</a></li>
|
||||
<li><a href="https://github.com/security" data-ga-click="Footer, go to security, text:security">Security</a></li>
|
||||
<li><a href="https://status.github.com/" data-ga-click="Footer, go to status, text:status">Status</a></li>
|
||||
<li><a href="https://help.github.com" data-ga-click="Footer, go to help, text:help">Help</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div id="ajax-error-message" class="ajax-error-message flash flash-error">
|
||||
<svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"></path></svg>
|
||||
<button type="button" class="flash-close js-flash-close js-ajax-error-dismiss" aria-label="Dismiss error">
|
||||
<svg aria-hidden="true" class="octicon octicon-x" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"></path></svg>
|
||||
</button>
|
||||
You can't perform that action at this time.
|
||||
</div>
|
||||
|
||||
|
||||
<script crossorigin="anonymous" src="https://assets-cdn.github.com/assets/compat-40e365359d1c4db1e36a55be458e60f2b7c24d58b5a00ae13398480e7ba768e0.js"></script>
|
||||
<script crossorigin="anonymous" src="https://assets-cdn.github.com/assets/frameworks-88471af1fec40ff9418efbe2ddd15b6896af8d772f8179004c254dffc25ea490.js"></script>
|
||||
<script async="async" crossorigin="anonymous" src="https://assets-cdn.github.com/assets/github-e18e11a943ff2eb9394c72d4ec8b76592c454915b5839ae177d422777a046e29.js"></script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="js-stale-session-flash stale-session-flash flash flash-warn flash-banner d-none">
|
||||
<svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"></path></svg>
|
||||
<span class="signed-in-tab-flash">You signed in with another tab or window. <a href="">Reload</a> to refresh your session.</span>
|
||||
<span class="signed-out-tab-flash">You signed out in another tab or window. <a href="">Reload</a> to refresh your session.</span>
|
||||
</div>
|
||||
<div class="facebox" id="facebox" style="display:none;">
|
||||
<div class="facebox-popup">
|
||||
<div class="facebox-content" role="dialog" aria-labelledby="facebox-header" aria-describedby="facebox-description">
|
||||
</div>
|
||||
<button type="button" class="facebox-close js-facebox-close" aria-label="Close modal">
|
||||
<svg aria-hidden="true" class="octicon octicon-x" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"></path></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
BIN
vendor/json/test/reports/2016-09-09-nativejson_benchmark/conformance_overall_Result.png
vendored
Normal file
|
After Width: | Height: | Size: 166 KiB |
|
After Width: | Height: | Size: 192 KiB |
|
After Width: | Height: | Size: 146 KiB |
|
After Width: | Height: | Size: 136 KiB |
|
After Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 182 KiB |
BIN
vendor/json/test/reports/2016-10-02-fuzz/exec_speed.png
vendored
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
vendor/json/test/reports/2016-10-02-fuzz/fuzz.tiff
vendored
Normal file
BIN
vendor/json/test/reports/2016-10-02-fuzz/high_freq.png
vendored
Normal file
|
After Width: | Height: | Size: 22 KiB |
10
vendor/json/test/reports/2016-10-02-fuzz/index.html
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<table style="font-family: 'Trebuchet MS', 'Tahoma', 'Arial', 'Helvetica'">
|
||||
<tr><td style="width: 18ex"><b>Banner:</b></td><td>fuzz</td></tr>
|
||||
<tr><td><b>Directory:</b></td><td>fuzz-testing/out</td></tr>
|
||||
<tr><td><b>Generated on:</b></td><td>Sun Oct 2 08:51:02 CEST 2016</td></tr>
|
||||
</table>
|
||||
<p>
|
||||
<img src="high_freq.png" width=1000 height=300><p>
|
||||
<img src="low_freq.png" width=1000 height=200><p>
|
||||
<img src="exec_speed.png" width=1000 height=200>
|
||||
|
||||
BIN
vendor/json/test/reports/2016-10-02-fuzz/low_freq.png
vendored
Normal file
|
After Width: | Height: | Size: 14 KiB |
1
vendor/json/test/src/UBSAN.supp
vendored
Normal file
@@ -0,0 +1 @@
|
||||
unsigned-integer-overflow:stl_bvector.h
|
||||
38
vendor/json/test/src/fuzzer-driver_afl.cpp
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
This file implements a driver for American Fuzzy Lop (afl-fuzz). It relies on
|
||||
an implementation of the `LLVMFuzzerTestOneInput` function which processes a
|
||||
passed byte array.
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
*/
|
||||
|
||||
#include <vector> // for vector
|
||||
#include <cstdint> // for uint8_t
|
||||
#include <iostream> // for cin
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef __AFL_HAVE_MANUAL_CONTROL
|
||||
while (__AFL_LOOP(1000))
|
||||
{
|
||||
#endif
|
||||
// copy stdin to byte vector
|
||||
std::vector<uint8_t> vec;
|
||||
char c;
|
||||
while (std::cin.get(c))
|
||||
{
|
||||
vec.push_back(static_cast<uint8_t>(c));
|
||||
}
|
||||
|
||||
LLVMFuzzerTestOneInput(vec.data(), vec.size());
|
||||
#ifdef __AFL_HAVE_MANUAL_CONTROL
|
||||
}
|
||||
#endif
|
||||
}
|
||||
73
vendor/json/test/src/fuzzer-parse_bson.cpp
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
This file implements a parser test suitable for fuzz testing. Given a byte
|
||||
array data, it performs the following steps:
|
||||
|
||||
- j1 = from_bson(data)
|
||||
- vec = to_bson(j1)
|
||||
- j2 = from_bson(vec)
|
||||
- assert(j1 == j2)
|
||||
|
||||
The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer
|
||||
drivers.
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
// see http://llvm.org/docs/LibFuzzer.html
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
|
||||
{
|
||||
try
|
||||
{
|
||||
// step 1: parse input
|
||||
std::vector<uint8_t> vec1(data, data + size);
|
||||
json j1 = json::from_bson(vec1);
|
||||
|
||||
if (j1.is_discarded())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// step 2: round trip
|
||||
std::vector<uint8_t> vec2 = json::to_bson(j1);
|
||||
|
||||
// parse serialization
|
||||
json j2 = json::from_bson(vec2);
|
||||
|
||||
// serializations must match
|
||||
assert(json::to_bson(j2) == vec2);
|
||||
}
|
||||
catch (const json::parse_error&)
|
||||
{
|
||||
// parsing a BSON serialization must not fail
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
catch (const json::parse_error&)
|
||||
{
|
||||
// parse errors are ok, because input may be random bytes
|
||||
}
|
||||
catch (const json::type_error&)
|
||||
{
|
||||
// type errors can occur during parsing, too
|
||||
}
|
||||
catch (const json::out_of_range&)
|
||||
{
|
||||
// out of range errors can occur during parsing, too
|
||||
}
|
||||
|
||||
// return 0 - non-zero return values are reserved for future use
|
||||
return 0;
|
||||
}
|
||||
68
vendor/json/test/src/fuzzer-parse_cbor.cpp
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
This file implements a parser test suitable for fuzz testing. Given a byte
|
||||
array data, it performs the following steps:
|
||||
|
||||
- j1 = from_cbor(data)
|
||||
- vec = to_cbor(j1)
|
||||
- j2 = from_cbor(vec)
|
||||
- assert(j1 == j2)
|
||||
|
||||
The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer
|
||||
drivers.
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
// see http://llvm.org/docs/LibFuzzer.html
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
|
||||
{
|
||||
try
|
||||
{
|
||||
// step 1: parse input
|
||||
std::vector<uint8_t> vec1(data, data + size);
|
||||
json j1 = json::from_cbor(vec1);
|
||||
|
||||
try
|
||||
{
|
||||
// step 2: round trip
|
||||
std::vector<uint8_t> vec2 = json::to_cbor(j1);
|
||||
|
||||
// parse serialization
|
||||
json j2 = json::from_cbor(vec2);
|
||||
|
||||
// serializations must match
|
||||
assert(json::to_cbor(j2) == vec2);
|
||||
}
|
||||
catch (const json::parse_error&)
|
||||
{
|
||||
// parsing a CBOR serialization must not fail
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
catch (const json::parse_error&)
|
||||
{
|
||||
// parse errors are ok, because input may be random bytes
|
||||
}
|
||||
catch (const json::type_error&)
|
||||
{
|
||||
// type errors can occur during parsing, too
|
||||
}
|
||||
catch (const json::out_of_range&)
|
||||
{
|
||||
// out of range errors can occur during parsing, too
|
||||
}
|
||||
|
||||
// return 0 - non-zero return values are reserved for future use
|
||||
return 0;
|
||||
}
|
||||
69
vendor/json/test/src/fuzzer-parse_json.cpp
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
This file implements a parser test suitable for fuzz testing. Given a byte
|
||||
array data, it performs the following steps:
|
||||
|
||||
- j1 = parse(data)
|
||||
- s1 = serialize(j1)
|
||||
- j2 = parse(s1)
|
||||
- s2 = serialize(j2)
|
||||
- assert(s1 == s2)
|
||||
|
||||
The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer
|
||||
drivers.
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
// see http://llvm.org/docs/LibFuzzer.html
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
|
||||
{
|
||||
try
|
||||
{
|
||||
// step 1: parse input
|
||||
json j1 = json::parse(data, data + size);
|
||||
|
||||
try
|
||||
{
|
||||
// step 2: round trip
|
||||
|
||||
// first serialization
|
||||
std::string s1 = j1.dump();
|
||||
|
||||
// parse serialization
|
||||
json j2 = json::parse(s1);
|
||||
|
||||
// second serialization
|
||||
std::string s2 = j2.dump();
|
||||
|
||||
// serializations must match
|
||||
assert(s1 == s2);
|
||||
}
|
||||
catch (const json::parse_error&)
|
||||
{
|
||||
// parsing a JSON serialization must not fail
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
catch (const json::parse_error&)
|
||||
{
|
||||
// parse errors are ok, because input may be random bytes
|
||||
}
|
||||
catch (const json::out_of_range&)
|
||||
{
|
||||
// out of range errors may happen if provided sizes are excessive
|
||||
}
|
||||
|
||||
// return 0 - non-zero return values are reserved for future use
|
||||
return 0;
|
||||
}
|
||||
68
vendor/json/test/src/fuzzer-parse_msgpack.cpp
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
This file implements a parser test suitable for fuzz testing. Given a byte
|
||||
array data, it performs the following steps:
|
||||
|
||||
- j1 = from_msgpack(data)
|
||||
- vec = to_msgpack(j1)
|
||||
- j2 = from_msgpack(vec)
|
||||
- assert(j1 == j2)
|
||||
|
||||
The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer
|
||||
drivers.
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
// see http://llvm.org/docs/LibFuzzer.html
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
|
||||
{
|
||||
try
|
||||
{
|
||||
// step 1: parse input
|
||||
std::vector<uint8_t> vec1(data, data + size);
|
||||
json j1 = json::from_msgpack(vec1);
|
||||
|
||||
try
|
||||
{
|
||||
// step 2: round trip
|
||||
std::vector<uint8_t> vec2 = json::to_msgpack(j1);
|
||||
|
||||
// parse serialization
|
||||
json j2 = json::from_msgpack(vec2);
|
||||
|
||||
// serializations must match
|
||||
assert(json::to_msgpack(j2) == vec2);
|
||||
}
|
||||
catch (const json::parse_error&)
|
||||
{
|
||||
// parsing a MessagePack serialization must not fail
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
catch (const json::parse_error&)
|
||||
{
|
||||
// parse errors are ok, because input may be random bytes
|
||||
}
|
||||
catch (const json::type_error&)
|
||||
{
|
||||
// type errors can occur during parsing, too
|
||||
}
|
||||
catch (const json::out_of_range&)
|
||||
{
|
||||
// out of range errors may happen if provided sizes are excessive
|
||||
}
|
||||
|
||||
// return 0 - non-zero return values are reserved for future use
|
||||
return 0;
|
||||
}
|
||||
84
vendor/json/test/src/fuzzer-parse_ubjson.cpp
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (fuzz test support)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
This file implements a parser test suitable for fuzz testing. Given a byte
|
||||
array data, it performs the following steps:
|
||||
|
||||
- j1 = from_ubjson(data)
|
||||
- vec = to_ubjson(j1)
|
||||
- j2 = from_ubjson(vec)
|
||||
- assert(j1 == j2)
|
||||
- vec2 = to_ubjson(j1, use_size = true, use_type = false)
|
||||
- j3 = from_ubjson(vec2)
|
||||
- assert(j1 == j3)
|
||||
- vec3 = to_ubjson(j1, use_size = true, use_type = true)
|
||||
- j4 = from_ubjson(vec3)
|
||||
- assert(j1 == j4)
|
||||
|
||||
The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer
|
||||
drivers.
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
// see http://llvm.org/docs/LibFuzzer.html
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
|
||||
{
|
||||
try
|
||||
{
|
||||
// step 1: parse input
|
||||
std::vector<uint8_t> vec1(data, data + size);
|
||||
json j1 = json::from_ubjson(vec1);
|
||||
|
||||
try
|
||||
{
|
||||
// step 2.1: round trip without adding size annotations to container types
|
||||
std::vector<uint8_t> vec2 = json::to_ubjson(j1, false, false);
|
||||
|
||||
// step 2.2: round trip with adding size annotations but without adding type annonations to container types
|
||||
std::vector<uint8_t> vec3 = json::to_ubjson(j1, true, false);
|
||||
|
||||
// step 2.3: round trip with adding size as well as type annotations to container types
|
||||
std::vector<uint8_t> vec4 = json::to_ubjson(j1, true, true);
|
||||
|
||||
// parse serialization
|
||||
json j2 = json::from_ubjson(vec2);
|
||||
json j3 = json::from_ubjson(vec3);
|
||||
json j4 = json::from_ubjson(vec4);
|
||||
|
||||
// serializations must match
|
||||
assert(json::to_ubjson(j2, false, false) == vec2);
|
||||
assert(json::to_ubjson(j3, true, false) == vec3);
|
||||
assert(json::to_ubjson(j4, true, true) == vec4);
|
||||
}
|
||||
catch (const json::parse_error&)
|
||||
{
|
||||
// parsing a UBJSON serialization must not fail
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
catch (const json::parse_error&)
|
||||
{
|
||||
// parse errors are ok, because input may be random bytes
|
||||
}
|
||||
catch (const json::type_error&)
|
||||
{
|
||||
// type errors can occur during parsing, too
|
||||
}
|
||||
catch (const json::out_of_range&)
|
||||
{
|
||||
// out of range errors may happen if provided sizes are excessive
|
||||
}
|
||||
|
||||
// return 0 - non-zero return values are reserved for future use
|
||||
return 0;
|
||||
}
|
||||
25
vendor/json/test/src/test_utils.hpp
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint> // uint8_t
|
||||
#include <fstream> // ifstream, istreambuf_iterator, ios
|
||||
#include <vector> // vector
|
||||
|
||||
namespace utils
|
||||
{
|
||||
|
||||
inline std::vector<std::uint8_t> read_binary_file(const std::string& filename)
|
||||
{
|
||||
std::ifstream file(filename, std::ios::binary);
|
||||
file.unsetf(std::ios::skipws);
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
const auto size = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
||||
std::vector<std::uint8_t> byte_vector;
|
||||
byte_vector.reserve(static_cast<std::size_t>(size));
|
||||
byte_vector.insert(byte_vector.begin(), std::istream_iterator<std::uint8_t>(file), std::istream_iterator<std::uint8_t>());
|
||||
return byte_vector;
|
||||
}
|
||||
|
||||
} // namespace utils
|
||||
320
vendor/json/test/src/unit-algorithms.cpp
vendored
Normal file
@@ -0,0 +1,320 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
TEST_CASE("algorithms")
|
||||
{
|
||||
json j_array = {13, 29, 3, {{"one", 1}, {"two", 2}}, true, false, {1, 2, 3}, "foo", "baz"};
|
||||
json j_object = {{"one", 1}, {"two", 2}};
|
||||
|
||||
SECTION("non-modifying sequence operations")
|
||||
{
|
||||
SECTION("std::all_of")
|
||||
{
|
||||
CHECK(std::all_of(j_array.begin(), j_array.end(), [](const json & value)
|
||||
{
|
||||
return value.size() > 0;
|
||||
}));
|
||||
CHECK(std::all_of(j_object.begin(), j_object.end(), [](const json & value)
|
||||
{
|
||||
return value.type() == json::value_t::number_integer;
|
||||
}));
|
||||
}
|
||||
|
||||
SECTION("std::any_of")
|
||||
{
|
||||
CHECK(std::any_of(j_array.begin(), j_array.end(), [](const json & value)
|
||||
{
|
||||
return value.is_string() && value.get<std::string>() == "foo";
|
||||
}));
|
||||
CHECK(std::any_of(j_object.begin(), j_object.end(), [](const json & value)
|
||||
{
|
||||
return value.get<int>() > 1;
|
||||
}));
|
||||
}
|
||||
|
||||
SECTION("std::none_of")
|
||||
{
|
||||
CHECK(std::none_of(j_array.begin(), j_array.end(), [](const json & value)
|
||||
{
|
||||
return value.size() == 0;
|
||||
}));
|
||||
CHECK(std::none_of(j_object.begin(), j_object.end(), [](const json & value)
|
||||
{
|
||||
return value.get<int>() <= 0;
|
||||
}));
|
||||
}
|
||||
|
||||
SECTION("std::for_each")
|
||||
{
|
||||
SECTION("reading")
|
||||
{
|
||||
int sum = 0;
|
||||
|
||||
std::for_each(j_array.cbegin(), j_array.cend(), [&sum](const json & value)
|
||||
{
|
||||
if (value.is_number())
|
||||
{
|
||||
sum += static_cast<int>(value);
|
||||
}
|
||||
});
|
||||
|
||||
CHECK(sum == 45);
|
||||
}
|
||||
|
||||
SECTION("writing")
|
||||
{
|
||||
auto add17 = [](json & value)
|
||||
{
|
||||
if (value.is_array())
|
||||
{
|
||||
value.push_back(17);
|
||||
}
|
||||
};
|
||||
|
||||
std::for_each(j_array.begin(), j_array.end(), add17);
|
||||
|
||||
CHECK(j_array[6] == json({1, 2, 3, 17}));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("std::count")
|
||||
{
|
||||
CHECK(std::count(j_array.begin(), j_array.end(), json(true)) == 1);
|
||||
}
|
||||
|
||||
SECTION("std::count_if")
|
||||
{
|
||||
CHECK(std::count_if(j_array.begin(), j_array.end(), [](const json & value)
|
||||
{
|
||||
return (value.is_number());
|
||||
}) == 3);
|
||||
CHECK(std::count_if(j_array.begin(), j_array.end(), [](const json&)
|
||||
{
|
||||
return true;
|
||||
}) == 9);
|
||||
}
|
||||
|
||||
SECTION("std::mismatch")
|
||||
{
|
||||
json j_array2 = {13, 29, 3, {{"one", 1}, {"two", 2}, {"three", 3}}, true, false, {1, 2, 3}, "foo", "baz"};
|
||||
auto res = std::mismatch(j_array.begin(), j_array.end(), j_array2.begin());
|
||||
CHECK(*res.first == json({{"one", 1}, {"two", 2}}));
|
||||
CHECK(*res.second == json({{"one", 1}, {"two", 2}, {"three", 3}}));
|
||||
}
|
||||
|
||||
SECTION("std::equal")
|
||||
{
|
||||
SECTION("using operator==")
|
||||
{
|
||||
CHECK(std::equal(j_array.begin(), j_array.end(), j_array.begin()));
|
||||
CHECK(std::equal(j_object.begin(), j_object.end(), j_object.begin()));
|
||||
CHECK(!std::equal(j_array.begin(), j_array.end(), j_object.begin()));
|
||||
}
|
||||
|
||||
SECTION("using user-defined comparison")
|
||||
{
|
||||
// compare objects only by size of its elements
|
||||
json j_array2 = {13, 29, 3, {"Hello", "World"}, true, false, {{"one", 1}, {"two", 2}, {"three", 3}}, "foo", "baz"};
|
||||
CHECK(!std::equal(j_array.begin(), j_array.end(), j_array2.begin()));
|
||||
CHECK(std::equal(j_array.begin(), j_array.end(), j_array2.begin(),
|
||||
[](const json & a, const json & b)
|
||||
{
|
||||
return (a.size() == b.size());
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("std::find")
|
||||
{
|
||||
auto it = std::find(j_array.begin(), j_array.end(), json(false));
|
||||
CHECK(std::distance(j_array.begin(), it) == 5);
|
||||
}
|
||||
|
||||
SECTION("std::find_if")
|
||||
{
|
||||
auto it = std::find_if(j_array.begin(), j_array.end(),
|
||||
[](const json & value)
|
||||
{
|
||||
return value.is_boolean();
|
||||
});
|
||||
CHECK(std::distance(j_array.begin(), it) == 4);
|
||||
}
|
||||
|
||||
SECTION("std::find_if_not")
|
||||
{
|
||||
auto it = std::find_if_not(j_array.begin(), j_array.end(),
|
||||
[](const json & value)
|
||||
{
|
||||
return value.is_number();
|
||||
});
|
||||
CHECK(std::distance(j_array.begin(), it) == 3);
|
||||
}
|
||||
|
||||
SECTION("std::adjacent_find")
|
||||
{
|
||||
CHECK(std::adjacent_find(j_array.begin(), j_array.end()) == j_array.end());
|
||||
CHECK(std::adjacent_find(j_array.begin(), j_array.end(),
|
||||
[](const json & v1, const json & v2)
|
||||
{
|
||||
return v1.type() == v2.type();
|
||||
}) == j_array.begin());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("modifying sequence operations")
|
||||
{
|
||||
SECTION("std::reverse")
|
||||
{
|
||||
std::reverse(j_array.begin(), j_array.end());
|
||||
CHECK(j_array == json({"baz", "foo", {1, 2, 3}, false, true, {{"one", 1}, {"two", 2}}, 3, 29, 13}));
|
||||
}
|
||||
|
||||
SECTION("std::rotate")
|
||||
{
|
||||
std::rotate(j_array.begin(), j_array.begin() + 1, j_array.end());
|
||||
CHECK(j_array == json({29, 3, {{"one", 1}, {"two", 2}}, true, false, {1, 2, 3}, "foo", "baz", 13}));
|
||||
}
|
||||
|
||||
SECTION("std::partition")
|
||||
{
|
||||
auto it = std::partition(j_array.begin(), j_array.end(), [](const json & v)
|
||||
{
|
||||
return v.is_string();
|
||||
});
|
||||
CHECK(std::distance(j_array.begin(), it) == 2);
|
||||
CHECK(!it[2].is_string());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("sorting operations")
|
||||
{
|
||||
SECTION("std::sort")
|
||||
{
|
||||
SECTION("with standard comparison")
|
||||
{
|
||||
json j = {13, 29, 3, {{"one", 1}, {"two", 2}}, true, false, {1, 2, 3}, "foo", "baz", nullptr};
|
||||
std::sort(j.begin(), j.end());
|
||||
CHECK(j == json({nullptr, false, true, 3, 13, 29, {{"one", 1}, {"two", 2}}, {1, 2, 3}, "baz", "foo"}));
|
||||
}
|
||||
|
||||
SECTION("with user-defined comparison")
|
||||
{
|
||||
json j = {3, {{"one", 1}, {"two", 2}}, {1, 2, 3}, nullptr};
|
||||
std::sort(j.begin(), j.end(), [](const json & a, const json & b)
|
||||
{
|
||||
return a.size() < b.size();
|
||||
});
|
||||
CHECK(j == json({nullptr, 3, {{"one", 1}, {"two", 2}}, {1, 2, 3}}));
|
||||
}
|
||||
|
||||
SECTION("sorting an object")
|
||||
{
|
||||
json j({{"one", 1}, {"two", 2}});
|
||||
CHECK_THROWS_AS(std::sort(j.begin(), j.end()), json::invalid_iterator&);
|
||||
CHECK_THROWS_WITH(std::sort(j.begin(), j.end()),
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("std::partial_sort")
|
||||
{
|
||||
json j = {13, 29, 3, {{"one", 1}, {"two", 2}}, true, false, {1, 2, 3}, "foo", "baz", nullptr};
|
||||
std::partial_sort(j.begin(), j.begin() + 4, j.end());
|
||||
CHECK(j == json({nullptr, false, true, 3, {{"one", 1}, {"two", 2}}, 29, {1, 2, 3}, "foo", "baz", 13}));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("set operations")
|
||||
{
|
||||
SECTION("std::merge")
|
||||
{
|
||||
{
|
||||
json j1 = {2, 4, 6, 8};
|
||||
json j2 = {1, 2, 3, 5, 7};
|
||||
json j3;
|
||||
|
||||
std::merge(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3));
|
||||
CHECK(j3 == json({1, 2, 2, 3, 4, 5, 6, 7, 8}));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("std::set_difference")
|
||||
{
|
||||
json j1 = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
json j2 = {1, 2, 3, 5, 7};
|
||||
json j3;
|
||||
|
||||
std::set_difference(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3));
|
||||
CHECK(j3 == json({4, 6, 8}));
|
||||
}
|
||||
|
||||
SECTION("std::set_intersection")
|
||||
{
|
||||
json j1 = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
json j2 = {1, 2, 3, 5, 7};
|
||||
json j3;
|
||||
|
||||
std::set_intersection(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3));
|
||||
CHECK(j3 == json({1, 2, 3, 5, 7}));
|
||||
}
|
||||
|
||||
SECTION("std::set_union")
|
||||
{
|
||||
json j1 = {2, 4, 6, 8};
|
||||
json j2 = {1, 2, 3, 5, 7};
|
||||
json j3;
|
||||
|
||||
std::set_union(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3));
|
||||
CHECK(j3 == json({1, 2, 3, 4, 5, 6, 7, 8}));
|
||||
}
|
||||
|
||||
SECTION("std::set_symmetric_difference")
|
||||
{
|
||||
json j1 = {2, 4, 6, 8};
|
||||
json j2 = {1, 2, 3, 5, 7};
|
||||
json j3;
|
||||
|
||||
std::set_symmetric_difference(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3));
|
||||
CHECK(j3 == json({1, 3, 4, 5, 6, 7, 8}));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("heap operations")
|
||||
{
|
||||
std::make_heap(j_array.begin(), j_array.end());
|
||||
CHECK(std::is_heap(j_array.begin(), j_array.end()));
|
||||
std::sort_heap(j_array.begin(), j_array.end());
|
||||
CHECK(j_array == json({false, true, 3, 13, 29, {{"one", 1}, {"two", 2}}, {1, 2, 3}, "baz", "foo"}));
|
||||
}
|
||||
}
|
||||
278
vendor/json/test/src/unit-allocator.cpp
vendored
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#define JSON_TESTS_PRIVATE
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
namespace
|
||||
{
|
||||
// special test case to check if memory is leaked if constructor throws
|
||||
template<class T>
|
||||
struct bad_allocator : std::allocator<T>
|
||||
{
|
||||
template<class... Args>
|
||||
void construct(T*, Args&& ...)
|
||||
{
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("bad_alloc")
|
||||
{
|
||||
SECTION("bad_alloc")
|
||||
{
|
||||
// create JSON type using the throwing allocator
|
||||
using bad_json = nlohmann::basic_json<std::map,
|
||||
std::vector,
|
||||
std::string,
|
||||
bool,
|
||||
std::int64_t,
|
||||
std::uint64_t,
|
||||
double,
|
||||
bad_allocator>;
|
||||
|
||||
// creating an object should throw
|
||||
CHECK_THROWS_AS(bad_json(bad_json::value_t::object), std::bad_alloc&);
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
bool next_construct_fails = false;
|
||||
bool next_destroy_fails = false;
|
||||
bool next_deallocate_fails = false;
|
||||
|
||||
template<class T>
|
||||
struct my_allocator : std::allocator<T>
|
||||
{
|
||||
using std::allocator<T>::allocator;
|
||||
|
||||
template<class... Args>
|
||||
void construct(T* p, Args&& ... args)
|
||||
{
|
||||
if (next_construct_fails)
|
||||
{
|
||||
next_construct_fails = false;
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
else
|
||||
{
|
||||
::new (reinterpret_cast<void*>(p)) T(std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
void deallocate(T* p, std::size_t n)
|
||||
{
|
||||
if (next_deallocate_fails)
|
||||
{
|
||||
next_deallocate_fails = false;
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::allocator<T>::deallocate(p, n);
|
||||
}
|
||||
}
|
||||
|
||||
void destroy(T* p)
|
||||
{
|
||||
if (next_destroy_fails)
|
||||
{
|
||||
next_destroy_fails = false;
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
else
|
||||
{
|
||||
p->~T();
|
||||
}
|
||||
}
|
||||
|
||||
template <class U>
|
||||
struct rebind
|
||||
{
|
||||
using other = my_allocator<U>;
|
||||
};
|
||||
};
|
||||
|
||||
// allows deletion of raw pointer, usually hold by json_value
|
||||
template<class T>
|
||||
void my_allocator_clean_up(T* p)
|
||||
{
|
||||
assert(p != nullptr);
|
||||
my_allocator<T> alloc;
|
||||
alloc.destroy(p);
|
||||
alloc.deallocate(p, 1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("controlled bad_alloc")
|
||||
{
|
||||
// create JSON type using the throwing allocator
|
||||
using my_json = nlohmann::basic_json<std::map,
|
||||
std::vector,
|
||||
std::string,
|
||||
bool,
|
||||
std::int64_t,
|
||||
std::uint64_t,
|
||||
double,
|
||||
my_allocator>;
|
||||
|
||||
SECTION("class json_value")
|
||||
{
|
||||
SECTION("json_value(value_t)")
|
||||
{
|
||||
SECTION("object")
|
||||
{
|
||||
next_construct_fails = false;
|
||||
auto t = my_json::value_t::object;
|
||||
CHECK_NOTHROW(my_allocator_clean_up(my_json::json_value(t).object));
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(my_json::json_value(t), std::bad_alloc&);
|
||||
next_construct_fails = false;
|
||||
}
|
||||
SECTION("array")
|
||||
{
|
||||
next_construct_fails = false;
|
||||
auto t = my_json::value_t::array;
|
||||
CHECK_NOTHROW(my_allocator_clean_up(my_json::json_value(t).array));
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(my_json::json_value(t), std::bad_alloc&);
|
||||
next_construct_fails = false;
|
||||
}
|
||||
SECTION("string")
|
||||
{
|
||||
next_construct_fails = false;
|
||||
auto t = my_json::value_t::string;
|
||||
CHECK_NOTHROW(my_allocator_clean_up(my_json::json_value(t).string));
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(my_json::json_value(t), std::bad_alloc&);
|
||||
next_construct_fails = false;
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("json_value(const string_t&)")
|
||||
{
|
||||
next_construct_fails = false;
|
||||
my_json::string_t v("foo");
|
||||
CHECK_NOTHROW(my_allocator_clean_up(my_json::json_value(v).string));
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(my_json::json_value(v), std::bad_alloc&);
|
||||
next_construct_fails = false;
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("class basic_json")
|
||||
{
|
||||
SECTION("basic_json(const CompatibleObjectType&)")
|
||||
{
|
||||
next_construct_fails = false;
|
||||
std::map<std::string, std::string> v {{"foo", "bar"}};
|
||||
CHECK_NOTHROW(my_json(v));
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(my_json(v), std::bad_alloc&);
|
||||
next_construct_fails = false;
|
||||
}
|
||||
|
||||
SECTION("basic_json(const CompatibleArrayType&)")
|
||||
{
|
||||
next_construct_fails = false;
|
||||
std::vector<std::string> v {"foo", "bar", "baz"};
|
||||
CHECK_NOTHROW(my_json(v));
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(my_json(v), std::bad_alloc&);
|
||||
next_construct_fails = false;
|
||||
}
|
||||
|
||||
SECTION("basic_json(const typename string_t::value_type*)")
|
||||
{
|
||||
next_construct_fails = false;
|
||||
CHECK_NOTHROW(my_json("foo"));
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(my_json("foo"), std::bad_alloc&);
|
||||
next_construct_fails = false;
|
||||
}
|
||||
|
||||
SECTION("basic_json(const typename string_t::value_type*)")
|
||||
{
|
||||
next_construct_fails = false;
|
||||
std::string s("foo");
|
||||
CHECK_NOTHROW(my_json(s));
|
||||
next_construct_fails = true;
|
||||
CHECK_THROWS_AS(my_json(s), std::bad_alloc&);
|
||||
next_construct_fails = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
template<class T>
|
||||
struct allocator_no_forward : std::allocator<T>
|
||||
{
|
||||
allocator_no_forward() {}
|
||||
template <class U>
|
||||
allocator_no_forward(allocator_no_forward<U>) {}
|
||||
|
||||
template <class U>
|
||||
struct rebind
|
||||
{
|
||||
using other = allocator_no_forward<U>;
|
||||
};
|
||||
|
||||
template <class... Args>
|
||||
void construct(T* p, const Args& ... args) noexcept(noexcept(::new (static_cast<void*>(p)) T(args...)))
|
||||
{
|
||||
// force copy even if move is available
|
||||
::new (static_cast<void*>(p)) T(args...);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("bad my_allocator::construct")
|
||||
{
|
||||
SECTION("my_allocator::construct doesn't forward")
|
||||
{
|
||||
using bad_alloc_json = nlohmann::basic_json<std::map,
|
||||
std::vector,
|
||||
std::string,
|
||||
bool,
|
||||
std::int64_t,
|
||||
std::uint64_t,
|
||||
double,
|
||||
allocator_no_forward>;
|
||||
|
||||
bad_alloc_json j;
|
||||
j["test"] = bad_alloc_json::array_t();
|
||||
j["test"].push_back("should not leak");
|
||||
}
|
||||
}
|
||||
299
vendor/json/test/src/unit-alt-string.cpp
vendored
Normal file
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2018 Vitaliy Manushkin <agri@akamo.info>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
|
||||
/* forward declarations */
|
||||
class alt_string;
|
||||
bool operator<(const char* op1, const alt_string& op2);
|
||||
void int_to_string(alt_string& target, std::size_t value);
|
||||
|
||||
/*
|
||||
* This is virtually a string class.
|
||||
* It covers std::string under the hood.
|
||||
*/
|
||||
class alt_string
|
||||
{
|
||||
public:
|
||||
using value_type = std::string::value_type;
|
||||
|
||||
alt_string(const char* str): str_impl(str) {}
|
||||
alt_string(const char* str, std::size_t count): str_impl(str, count) {}
|
||||
alt_string(size_t count, char chr): str_impl(count, chr) {}
|
||||
alt_string() = default;
|
||||
|
||||
template <typename...TParams>
|
||||
alt_string& append(TParams&& ...params)
|
||||
{
|
||||
str_impl.append(std::forward<TParams>(params)...);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void push_back(char c)
|
||||
{
|
||||
str_impl.push_back(c);
|
||||
}
|
||||
|
||||
template <typename op_type>
|
||||
bool operator==(const op_type& op) const
|
||||
{
|
||||
return str_impl == op;
|
||||
}
|
||||
|
||||
bool operator==(const alt_string& op) const
|
||||
{
|
||||
return str_impl == op.str_impl;
|
||||
}
|
||||
|
||||
template <typename op_type>
|
||||
bool operator!=(const op_type& op) const
|
||||
{
|
||||
return str_impl != op;
|
||||
}
|
||||
|
||||
bool operator!=(const alt_string& op) const
|
||||
{
|
||||
return str_impl != op.str_impl;
|
||||
}
|
||||
|
||||
std::size_t size() const noexcept
|
||||
{
|
||||
return str_impl.size();
|
||||
}
|
||||
|
||||
void resize (std::size_t n)
|
||||
{
|
||||
str_impl.resize(n);
|
||||
}
|
||||
|
||||
void resize (std::size_t n, char c)
|
||||
{
|
||||
str_impl.resize(n, c);
|
||||
}
|
||||
|
||||
template <typename op_type>
|
||||
bool operator<(const op_type& op) const
|
||||
{
|
||||
return str_impl < op;
|
||||
}
|
||||
|
||||
bool operator<(const alt_string& op) const
|
||||
{
|
||||
return str_impl < op.str_impl;
|
||||
}
|
||||
|
||||
const char* c_str() const
|
||||
{
|
||||
return str_impl.c_str();
|
||||
}
|
||||
|
||||
char& operator[](std::size_t index)
|
||||
{
|
||||
return str_impl[index];
|
||||
}
|
||||
|
||||
const char& operator[](std::size_t index) const
|
||||
{
|
||||
return str_impl[index];
|
||||
}
|
||||
|
||||
char& back()
|
||||
{
|
||||
return str_impl.back();
|
||||
}
|
||||
|
||||
const char& back() const
|
||||
{
|
||||
return str_impl.back();
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
str_impl.clear();
|
||||
}
|
||||
|
||||
const value_type* data()
|
||||
{
|
||||
return str_impl.data();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string str_impl {};
|
||||
|
||||
friend bool ::operator<(const char*, const alt_string&);
|
||||
};
|
||||
|
||||
void int_to_string(alt_string& target, std::size_t value)
|
||||
{
|
||||
target = std::to_string(value).c_str();
|
||||
}
|
||||
|
||||
using alt_json = nlohmann::basic_json <
|
||||
std::map,
|
||||
std::vector,
|
||||
alt_string,
|
||||
bool,
|
||||
std::int64_t,
|
||||
std::uint64_t,
|
||||
double,
|
||||
std::allocator,
|
||||
nlohmann::adl_serializer >;
|
||||
|
||||
|
||||
bool operator<(const char* op1, const alt_string& op2)
|
||||
{
|
||||
return op1 < op2.str_impl;
|
||||
}
|
||||
|
||||
TEST_CASE("alternative string type")
|
||||
{
|
||||
SECTION("dump")
|
||||
{
|
||||
{
|
||||
alt_json doc;
|
||||
doc["pi"] = 3.141;
|
||||
alt_string dump = doc.dump();
|
||||
CHECK(dump == R"({"pi":3.141})");
|
||||
}
|
||||
|
||||
{
|
||||
alt_json doc;
|
||||
doc["happy"] = true;
|
||||
alt_string dump = doc.dump();
|
||||
CHECK(dump == R"({"happy":true})");
|
||||
}
|
||||
|
||||
{
|
||||
alt_json doc;
|
||||
doc["name"] = "I'm Batman";
|
||||
alt_string dump = doc.dump();
|
||||
CHECK(dump == R"({"name":"I'm Batman"})");
|
||||
}
|
||||
|
||||
{
|
||||
alt_json doc;
|
||||
doc["nothing"] = nullptr;
|
||||
alt_string dump = doc.dump();
|
||||
CHECK(dump == R"({"nothing":null})");
|
||||
}
|
||||
|
||||
{
|
||||
alt_json doc;
|
||||
doc["answer"]["everything"] = 42;
|
||||
alt_string dump = doc.dump();
|
||||
CHECK(dump == R"({"answer":{"everything":42}})");
|
||||
}
|
||||
|
||||
{
|
||||
alt_json doc;
|
||||
doc["list"] = { 1, 0, 2 };
|
||||
alt_string dump = doc.dump();
|
||||
CHECK(dump == R"({"list":[1,0,2]})");
|
||||
}
|
||||
|
||||
{
|
||||
alt_json doc;
|
||||
doc["object"] = { {"currency", "USD"}, {"value", 42.99} };
|
||||
alt_string dump = doc.dump();
|
||||
CHECK(dump == R"({"object":{"currency":"USD","value":42.99}})");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("parse")
|
||||
{
|
||||
auto doc = alt_json::parse("{\"foo\": \"bar\"}");
|
||||
alt_string dump = doc.dump();
|
||||
CHECK(dump == R"({"foo":"bar"})");
|
||||
}
|
||||
|
||||
SECTION("items")
|
||||
{
|
||||
auto doc = alt_json::parse("{\"foo\": \"bar\"}");
|
||||
|
||||
for ( auto item : doc.items() )
|
||||
{
|
||||
CHECK( item.key() == "foo" );
|
||||
CHECK( item.value() == "bar" );
|
||||
}
|
||||
|
||||
auto doc_array = alt_json::parse("[\"foo\", \"bar\"]");
|
||||
|
||||
for ( auto item : doc_array.items() )
|
||||
{
|
||||
if (item.key() == "0" )
|
||||
{
|
||||
CHECK( item.value() == "foo" );
|
||||
}
|
||||
else if (item.key() == "1" )
|
||||
{
|
||||
CHECK( item.value() == "bar" );
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("equality")
|
||||
{
|
||||
alt_json doc;
|
||||
doc["Who are you?"] = "I'm Batman";
|
||||
|
||||
CHECK("I'm Batman" == doc["Who are you?"]);
|
||||
CHECK(doc["Who are you?"] == "I'm Batman");
|
||||
CHECK_FALSE("I'm Batman" != doc["Who are you?"]);
|
||||
CHECK_FALSE(doc["Who are you?"] != "I'm Batman");
|
||||
|
||||
CHECK("I'm Bruce Wayne" != doc["Who are you?"]);
|
||||
CHECK(doc["Who are you?"] != "I'm Bruce Wayne");
|
||||
CHECK_FALSE("I'm Bruce Wayne" == doc["Who are you?"]);
|
||||
CHECK_FALSE(doc["Who are you?"] == "I'm Bruce Wayne");
|
||||
|
||||
{
|
||||
const alt_json& const_doc = doc;
|
||||
|
||||
CHECK("I'm Batman" == const_doc["Who are you?"]);
|
||||
CHECK(const_doc["Who are you?"] == "I'm Batman");
|
||||
CHECK_FALSE("I'm Batman" != const_doc["Who are you?"]);
|
||||
CHECK_FALSE(const_doc["Who are you?"] != "I'm Batman");
|
||||
|
||||
CHECK("I'm Bruce Wayne" != const_doc["Who are you?"]);
|
||||
CHECK(const_doc["Who are you?"] != "I'm Bruce Wayne");
|
||||
CHECK_FALSE("I'm Bruce Wayne" == const_doc["Who are you?"]);
|
||||
CHECK_FALSE(const_doc["Who are you?"] == "I'm Bruce Wayne");
|
||||
}
|
||||
}
|
||||
}
|
||||
65
vendor/json/test/src/unit-assert_macro.cpp
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
// avoid warning when assert does not abort
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow"
|
||||
#endif
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
/// global variable to record side effect of assert calls
|
||||
static int assert_counter;
|
||||
|
||||
/// set failure variable to true instead of calling assert(x)
|
||||
#define JSON_ASSERT(x) {if (!(x)) ++assert_counter; }
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
// the test assumes exceptions to work
|
||||
#if !defined(JSON_NOEXCEPTION)
|
||||
TEST_CASE("JSON_ASSERT(x)")
|
||||
{
|
||||
SECTION("basic_json(first, second)")
|
||||
{
|
||||
assert_counter = 0;
|
||||
CHECK(assert_counter == 0);
|
||||
|
||||
json::iterator it;
|
||||
json j;
|
||||
|
||||
// in case assertions do not abort execution, an exception is thrown
|
||||
CHECK_THROWS_WITH_AS(json(it, j.end()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator);
|
||||
|
||||
// check that assertion actually happened
|
||||
CHECK(assert_counter == 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
1339
vendor/json/test/src/unit-bson.cpp
vendored
Normal file
563
vendor/json/test/src/unit-capacity.cpp
vendored
Normal file
@@ -0,0 +1,563 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
TEST_CASE("capacity")
|
||||
{
|
||||
SECTION("empty()")
|
||||
{
|
||||
SECTION("boolean")
|
||||
{
|
||||
json j = true;
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of empty")
|
||||
{
|
||||
CHECK(j.empty() == false);
|
||||
CHECK(j_const.empty() == false);
|
||||
}
|
||||
|
||||
SECTION("definition of empty")
|
||||
{
|
||||
CHECK(j.empty() == (j.begin() == j.end()));
|
||||
CHECK(j_const.empty() == (j_const.begin() == j_const.end()));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("string")
|
||||
{
|
||||
json j = "hello world";
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of empty")
|
||||
{
|
||||
CHECK(j.empty() == false);
|
||||
CHECK(j_const.empty() == false);
|
||||
}
|
||||
|
||||
SECTION("definition of empty")
|
||||
{
|
||||
CHECK(j.empty() == (j.begin() == j.end()));
|
||||
CHECK(j_const.empty() == (j_const.begin() == j_const.end()));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
SECTION("empty array")
|
||||
{
|
||||
json j = json::array();
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of empty")
|
||||
{
|
||||
CHECK(j.empty() == true);
|
||||
CHECK(j_const.empty() == true);
|
||||
}
|
||||
|
||||
SECTION("definition of empty")
|
||||
{
|
||||
CHECK(j.empty() == (j.begin() == j.end()));
|
||||
CHECK(j_const.empty() == (j_const.begin() == j_const.end()));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("filled array")
|
||||
{
|
||||
json j = {1, 2, 3};
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of empty")
|
||||
{
|
||||
CHECK(j.empty() == false);
|
||||
CHECK(j_const.empty() == false);
|
||||
}
|
||||
|
||||
SECTION("definition of empty")
|
||||
{
|
||||
CHECK(j.empty() == (j.begin() == j.end()));
|
||||
CHECK(j_const.empty() == (j_const.begin() == j_const.end()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
SECTION("empty object")
|
||||
{
|
||||
json j = json::object();
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of empty")
|
||||
{
|
||||
CHECK(j.empty() == true);
|
||||
CHECK(j_const.empty() == true);
|
||||
}
|
||||
|
||||
SECTION("definition of empty")
|
||||
{
|
||||
CHECK(j.empty() == (j.begin() == j.end()));
|
||||
CHECK(j_const.empty() == (j_const.begin() == j_const.end()));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("filled object")
|
||||
{
|
||||
json j = {{"one", 1}, {"two", 2}, {"three", 3}};
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of empty")
|
||||
{
|
||||
CHECK(j.empty() == false);
|
||||
CHECK(j_const.empty() == false);
|
||||
}
|
||||
|
||||
SECTION("definition of empty")
|
||||
{
|
||||
CHECK(j.empty() == (j.begin() == j.end()));
|
||||
CHECK(j_const.empty() == (j_const.begin() == j_const.end()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (integer)")
|
||||
{
|
||||
json j = -23;
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of empty")
|
||||
{
|
||||
CHECK(j.empty() == false);
|
||||
CHECK(j_const.empty() == false);
|
||||
}
|
||||
|
||||
SECTION("definition of empty")
|
||||
{
|
||||
CHECK(j.empty() == (j.begin() == j.end()));
|
||||
CHECK(j_const.empty() == (j_const.begin() == j_const.end()));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (unsigned)")
|
||||
{
|
||||
json j = 23u;
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of empty")
|
||||
{
|
||||
CHECK(j.empty() == false);
|
||||
CHECK(j_const.empty() == false);
|
||||
}
|
||||
|
||||
SECTION("definition of empty")
|
||||
{
|
||||
CHECK(j.empty() == (j.begin() == j.end()));
|
||||
CHECK(j_const.empty() == (j_const.begin() == j_const.end()));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (float)")
|
||||
{
|
||||
json j = 23.42;
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of empty")
|
||||
{
|
||||
CHECK(j.empty() == false);
|
||||
CHECK(j_const.empty() == false);
|
||||
}
|
||||
|
||||
SECTION("definition of empty")
|
||||
{
|
||||
CHECK(j.empty() == (j.begin() == j.end()));
|
||||
CHECK(j_const.empty() == (j_const.begin() == j_const.end()));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("null")
|
||||
{
|
||||
json j = nullptr;
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of empty")
|
||||
{
|
||||
CHECK(j.empty() == true);
|
||||
CHECK(j_const.empty() == true);
|
||||
}
|
||||
|
||||
SECTION("definition of empty")
|
||||
{
|
||||
CHECK(j.empty() == (j.begin() == j.end()));
|
||||
CHECK(j_const.empty() == (j_const.begin() == j_const.end()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("size()")
|
||||
{
|
||||
SECTION("boolean")
|
||||
{
|
||||
json j = true;
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of size")
|
||||
{
|
||||
CHECK(j.size() == 1);
|
||||
CHECK(j_const.size() == 1);
|
||||
}
|
||||
|
||||
SECTION("definition of size")
|
||||
{
|
||||
CHECK(std::distance(j.begin(), j.end()) == j.size());
|
||||
CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
|
||||
CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
|
||||
CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("string")
|
||||
{
|
||||
json j = "hello world";
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of size")
|
||||
{
|
||||
CHECK(j.size() == 1);
|
||||
CHECK(j_const.size() == 1);
|
||||
}
|
||||
|
||||
SECTION("definition of size")
|
||||
{
|
||||
CHECK(std::distance(j.begin(), j.end()) == j.size());
|
||||
CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
|
||||
CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
|
||||
CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
SECTION("empty array")
|
||||
{
|
||||
json j = json::array();
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of size")
|
||||
{
|
||||
CHECK(j.size() == 0);
|
||||
CHECK(j_const.size() == 0);
|
||||
}
|
||||
|
||||
SECTION("definition of size")
|
||||
{
|
||||
CHECK(std::distance(j.begin(), j.end()) == j.size());
|
||||
CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
|
||||
CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
|
||||
CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("filled array")
|
||||
{
|
||||
json j = {1, 2, 3};
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of size")
|
||||
{
|
||||
CHECK(j.size() == 3);
|
||||
CHECK(j_const.size() == 3);
|
||||
}
|
||||
|
||||
SECTION("definition of size")
|
||||
{
|
||||
CHECK(std::distance(j.begin(), j.end()) == j.size());
|
||||
CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
|
||||
CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
|
||||
CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
SECTION("empty object")
|
||||
{
|
||||
json j = json::object();
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of size")
|
||||
{
|
||||
CHECK(j.size() == 0);
|
||||
CHECK(j_const.size() == 0);
|
||||
}
|
||||
|
||||
SECTION("definition of size")
|
||||
{
|
||||
CHECK(std::distance(j.begin(), j.end()) == j.size());
|
||||
CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
|
||||
CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
|
||||
CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("filled object")
|
||||
{
|
||||
json j = {{"one", 1}, {"two", 2}, {"three", 3}};
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of size")
|
||||
{
|
||||
CHECK(j.size() == 3);
|
||||
CHECK(j_const.size() == 3);
|
||||
}
|
||||
|
||||
SECTION("definition of size")
|
||||
{
|
||||
CHECK(std::distance(j.begin(), j.end()) == j.size());
|
||||
CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
|
||||
CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
|
||||
CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (integer)")
|
||||
{
|
||||
json j = -23;
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of size")
|
||||
{
|
||||
CHECK(j.size() == 1);
|
||||
CHECK(j_const.size() == 1);
|
||||
}
|
||||
|
||||
SECTION("definition of size")
|
||||
{
|
||||
CHECK(std::distance(j.begin(), j.end()) == j.size());
|
||||
CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
|
||||
CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
|
||||
CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (unsigned)")
|
||||
{
|
||||
json j = 23u;
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of size")
|
||||
{
|
||||
CHECK(j.size() == 1);
|
||||
CHECK(j_const.size() == 1);
|
||||
}
|
||||
|
||||
SECTION("definition of size")
|
||||
{
|
||||
CHECK(std::distance(j.begin(), j.end()) == j.size());
|
||||
CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
|
||||
CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
|
||||
CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (float)")
|
||||
{
|
||||
json j = 23.42;
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of size")
|
||||
{
|
||||
CHECK(j.size() == 1);
|
||||
CHECK(j_const.size() == 1);
|
||||
}
|
||||
|
||||
SECTION("definition of size")
|
||||
{
|
||||
CHECK(std::distance(j.begin(), j.end()) == j.size());
|
||||
CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
|
||||
CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
|
||||
CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("null")
|
||||
{
|
||||
json j = nullptr;
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of size")
|
||||
{
|
||||
CHECK(j.size() == 0);
|
||||
CHECK(j_const.size() == 0);
|
||||
}
|
||||
|
||||
SECTION("definition of size")
|
||||
{
|
||||
CHECK(std::distance(j.begin(), j.end()) == j.size());
|
||||
CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
|
||||
CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
|
||||
CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("max_size()")
|
||||
{
|
||||
SECTION("boolean")
|
||||
{
|
||||
json j = true;
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of max_size")
|
||||
{
|
||||
CHECK(j.max_size() == 1);
|
||||
CHECK(j_const.max_size() == 1);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("string")
|
||||
{
|
||||
json j = "hello world";
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of max_size")
|
||||
{
|
||||
CHECK(j.max_size() == 1);
|
||||
CHECK(j_const.max_size() == 1);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
SECTION("empty array")
|
||||
{
|
||||
json j = json::array();
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of max_size")
|
||||
{
|
||||
CHECK(j.max_size() >= j.size());
|
||||
CHECK(j_const.max_size() >= j_const.size());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("filled array")
|
||||
{
|
||||
json j = {1, 2, 3};
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of max_size")
|
||||
{
|
||||
CHECK(j.max_size() >= j.size());
|
||||
CHECK(j_const.max_size() >= j_const.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
SECTION("empty object")
|
||||
{
|
||||
json j = json::object();
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of max_size")
|
||||
{
|
||||
CHECK(j.max_size() >= j.size());
|
||||
CHECK(j_const.max_size() >= j_const.size());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("filled object")
|
||||
{
|
||||
json j = {{"one", 1}, {"two", 2}, {"three", 3}};
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of max_size")
|
||||
{
|
||||
CHECK(j.max_size() >= j.size());
|
||||
CHECK(j_const.max_size() >= j_const.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (integer)")
|
||||
{
|
||||
json j = -23;
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of max_size")
|
||||
{
|
||||
CHECK(j.max_size() == 1);
|
||||
CHECK(j_const.max_size() == 1);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (unsigned)")
|
||||
{
|
||||
json j = 23u;
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of max_size")
|
||||
{
|
||||
CHECK(j.max_size() == 1);
|
||||
CHECK(j_const.max_size() == 1);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("number (float)")
|
||||
{
|
||||
json j = 23.42;
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of max_size")
|
||||
{
|
||||
CHECK(j.max_size() == 1);
|
||||
CHECK(j_const.max_size() == 1);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("null")
|
||||
{
|
||||
json j = nullptr;
|
||||
const json j_const(j);
|
||||
|
||||
SECTION("result of max_size")
|
||||
{
|
||||
CHECK(j.max_size() == 0);
|
||||
CHECK(j_const.max_size() == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2741
vendor/json/test/src/unit-cbor.cpp
vendored
Normal file
418
vendor/json/test/src/unit-class_const_iterator.cpp
vendored
Normal file
@@ -0,0 +1,418 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#define JSON_TESTS_PRIVATE
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
TEST_CASE("const_iterator class")
|
||||
{
|
||||
SECTION("construction")
|
||||
{
|
||||
SECTION("constructor")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j(json::value_t::null);
|
||||
json::const_iterator it(&j);
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j(json::value_t::object);
|
||||
json::const_iterator it(&j);
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j(json::value_t::array);
|
||||
json::const_iterator it(&j);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("copy assignment")
|
||||
{
|
||||
json j(json::value_t::null);
|
||||
json::const_iterator it(&j);
|
||||
json::const_iterator it2(&j);
|
||||
it2 = it;
|
||||
}
|
||||
|
||||
SECTION("copy constructor from non-const iterator")
|
||||
{
|
||||
SECTION("create from uninitialized iterator")
|
||||
{
|
||||
const json::iterator it {};
|
||||
json::const_iterator cit(it);
|
||||
}
|
||||
|
||||
SECTION("create from initialized iterator")
|
||||
{
|
||||
json j;
|
||||
const json::iterator it = j.begin();
|
||||
json::const_iterator cit(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("initialization")
|
||||
{
|
||||
SECTION("set_begin")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j(json::value_t::null);
|
||||
json::const_iterator it(&j);
|
||||
it.set_begin();
|
||||
CHECK((it == j.cbegin()));
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j(json::value_t::object);
|
||||
json::const_iterator it(&j);
|
||||
it.set_begin();
|
||||
CHECK((it == j.cbegin()));
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j(json::value_t::array);
|
||||
json::const_iterator it(&j);
|
||||
it.set_begin();
|
||||
CHECK((it == j.cbegin()));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("set_end")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j(json::value_t::null);
|
||||
json::const_iterator it(&j);
|
||||
it.set_end();
|
||||
CHECK((it == j.cend()));
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j(json::value_t::object);
|
||||
json::const_iterator it(&j);
|
||||
it.set_end();
|
||||
CHECK((it == j.cend()));
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j(json::value_t::array);
|
||||
json::const_iterator it(&j);
|
||||
it.set_end();
|
||||
CHECK((it == j.cend()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("element access")
|
||||
{
|
||||
SECTION("operator*")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j(json::value_t::null);
|
||||
json::const_iterator it = j.cbegin();
|
||||
CHECK_THROWS_AS(*it, json::invalid_iterator&);
|
||||
CHECK_THROWS_WITH(*it, "[json.exception.invalid_iterator.214] cannot get value");
|
||||
}
|
||||
|
||||
SECTION("number")
|
||||
{
|
||||
json j(17);
|
||||
json::const_iterator it = j.cbegin();
|
||||
CHECK(*it == json(17));
|
||||
it = j.cend();
|
||||
CHECK_THROWS_AS(*it, json::invalid_iterator&);
|
||||
CHECK_THROWS_WITH(*it, "[json.exception.invalid_iterator.214] cannot get value");
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j({{"foo", "bar"}});
|
||||
json::const_iterator it = j.cbegin();
|
||||
CHECK(*it == json("bar"));
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j({1, 2, 3, 4});
|
||||
json::const_iterator it = j.cbegin();
|
||||
CHECK(*it == json(1));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("operator->")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j(json::value_t::null);
|
||||
json::const_iterator it = j.cbegin();
|
||||
CHECK_THROWS_AS(std::string(it->type_name()), json::invalid_iterator&);
|
||||
CHECK_THROWS_WITH(std::string(it->type_name()), "[json.exception.invalid_iterator.214] cannot get value");
|
||||
}
|
||||
|
||||
SECTION("number")
|
||||
{
|
||||
json j(17);
|
||||
json::const_iterator it = j.cbegin();
|
||||
CHECK(std::string(it->type_name()) == "number");
|
||||
it = j.cend();
|
||||
CHECK_THROWS_AS(std::string(it->type_name()), json::invalid_iterator&);
|
||||
CHECK_THROWS_WITH(std::string(it->type_name()), "[json.exception.invalid_iterator.214] cannot get value");
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j({{"foo", "bar"}});
|
||||
json::const_iterator it = j.cbegin();
|
||||
CHECK(std::string(it->type_name()) == "string");
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j({1, 2, 3, 4});
|
||||
json::const_iterator it = j.cbegin();
|
||||
CHECK(std::string(it->type_name()) == "number");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("increment/decrement")
|
||||
{
|
||||
SECTION("post-increment")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j(json::value_t::null);
|
||||
json::const_iterator it = j.cbegin();
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 1));
|
||||
it++;
|
||||
CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
|
||||
}
|
||||
|
||||
SECTION("number")
|
||||
{
|
||||
json j(17);
|
||||
json::const_iterator it = j.cbegin();
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 0));
|
||||
it++;
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 1));
|
||||
it++;
|
||||
CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j({{"foo", "bar"}});
|
||||
json::const_iterator it = j.cbegin();
|
||||
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin()));
|
||||
it++;
|
||||
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end()));
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j({1, 2, 3, 4});
|
||||
json::const_iterator it = j.cbegin();
|
||||
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin()));
|
||||
it++;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
it++;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
it++;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
it++;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end()));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("pre-increment")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j(json::value_t::null);
|
||||
json::const_iterator it = j.cbegin();
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 1));
|
||||
++it;
|
||||
CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
|
||||
}
|
||||
|
||||
SECTION("number")
|
||||
{
|
||||
json j(17);
|
||||
json::const_iterator it = j.cbegin();
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 0));
|
||||
++it;
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 1));
|
||||
++it;
|
||||
CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j({{"foo", "bar"}});
|
||||
json::const_iterator it = j.cbegin();
|
||||
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin()));
|
||||
++it;
|
||||
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end()));
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j({1, 2, 3, 4});
|
||||
json::const_iterator it = j.cbegin();
|
||||
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin()));
|
||||
++it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
++it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
++it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
++it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end()));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("post-decrement")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j(json::value_t::null);
|
||||
json::const_iterator it = j.cend();
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 1));
|
||||
}
|
||||
|
||||
SECTION("number")
|
||||
{
|
||||
json j(17);
|
||||
json::const_iterator it = j.cend();
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 1));
|
||||
it--;
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 0));
|
||||
it--;
|
||||
CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j({{"foo", "bar"}});
|
||||
json::const_iterator it = j.cend();
|
||||
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end()));
|
||||
it--;
|
||||
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin()));
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j({1, 2, 3, 4});
|
||||
json::const_iterator it = j.cend();
|
||||
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end()));
|
||||
it--;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
it--;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
it--;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
it--;
|
||||
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("pre-decrement")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j(json::value_t::null);
|
||||
json::const_iterator it = j.cend();
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 1));
|
||||
}
|
||||
|
||||
SECTION("number")
|
||||
{
|
||||
json j(17);
|
||||
json::const_iterator it = j.cend();
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 1));
|
||||
--it;
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 0));
|
||||
--it;
|
||||
CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j({{"foo", "bar"}});
|
||||
json::const_iterator it = j.cend();
|
||||
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end()));
|
||||
--it;
|
||||
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin()));
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j({1, 2, 3, 4});
|
||||
json::const_iterator it = j.cend();
|
||||
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end()));
|
||||
--it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
--it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
--it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
--it;
|
||||
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
402
vendor/json/test/src/unit-class_iterator.cpp
vendored
Normal file
@@ -0,0 +1,402 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#define JSON_TESTS_PRIVATE
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
TEST_CASE("iterator class")
|
||||
{
|
||||
SECTION("construction")
|
||||
{
|
||||
SECTION("constructor")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j(json::value_t::null);
|
||||
json::iterator it(&j);
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j(json::value_t::object);
|
||||
json::iterator it(&j);
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j(json::value_t::array);
|
||||
json::iterator it(&j);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("copy assignment")
|
||||
{
|
||||
json j(json::value_t::null);
|
||||
json::iterator it(&j);
|
||||
json::iterator it2(&j);
|
||||
it2 = it;
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("initialization")
|
||||
{
|
||||
SECTION("set_begin")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j(json::value_t::null);
|
||||
json::iterator it(&j);
|
||||
it.set_begin();
|
||||
CHECK((it == j.begin()));
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j(json::value_t::object);
|
||||
json::iterator it(&j);
|
||||
it.set_begin();
|
||||
CHECK((it == j.begin()));
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j(json::value_t::array);
|
||||
json::iterator it(&j);
|
||||
it.set_begin();
|
||||
CHECK((it == j.begin()));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("set_end")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j(json::value_t::null);
|
||||
json::iterator it(&j);
|
||||
it.set_end();
|
||||
CHECK((it == j.end()));
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j(json::value_t::object);
|
||||
json::iterator it(&j);
|
||||
it.set_end();
|
||||
CHECK((it == j.end()));
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j(json::value_t::array);
|
||||
json::iterator it(&j);
|
||||
it.set_end();
|
||||
CHECK((it == j.end()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("element access")
|
||||
{
|
||||
SECTION("operator*")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j(json::value_t::null);
|
||||
json::iterator it = j.begin();
|
||||
CHECK_THROWS_AS(*it, json::invalid_iterator&);
|
||||
CHECK_THROWS_WITH(*it, "[json.exception.invalid_iterator.214] cannot get value");
|
||||
}
|
||||
|
||||
SECTION("number")
|
||||
{
|
||||
json j(17);
|
||||
json::iterator it = j.begin();
|
||||
CHECK(*it == json(17));
|
||||
it = j.end();
|
||||
CHECK_THROWS_AS(*it, json::invalid_iterator&);
|
||||
CHECK_THROWS_WITH(*it, "[json.exception.invalid_iterator.214] cannot get value");
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j({{"foo", "bar"}});
|
||||
json::iterator it = j.begin();
|
||||
CHECK(*it == json("bar"));
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j({1, 2, 3, 4});
|
||||
json::iterator it = j.begin();
|
||||
CHECK(*it == json(1));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("operator->")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j(json::value_t::null);
|
||||
json::iterator it = j.begin();
|
||||
CHECK_THROWS_AS(std::string(it->type_name()), json::invalid_iterator&);
|
||||
CHECK_THROWS_WITH(std::string(it->type_name()), "[json.exception.invalid_iterator.214] cannot get value");
|
||||
}
|
||||
|
||||
SECTION("number")
|
||||
{
|
||||
json j(17);
|
||||
json::iterator it = j.begin();
|
||||
CHECK(std::string(it->type_name()) == "number");
|
||||
it = j.end();
|
||||
CHECK_THROWS_AS(std::string(it->type_name()), json::invalid_iterator&);
|
||||
CHECK_THROWS_WITH(std::string(it->type_name()), "[json.exception.invalid_iterator.214] cannot get value");
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j({{"foo", "bar"}});
|
||||
json::iterator it = j.begin();
|
||||
CHECK(std::string(it->type_name()) == "string");
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j({1, 2, 3, 4});
|
||||
json::iterator it = j.begin();
|
||||
CHECK(std::string(it->type_name()) == "number");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("increment/decrement")
|
||||
{
|
||||
SECTION("post-increment")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j(json::value_t::null);
|
||||
json::iterator it = j.begin();
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 1));
|
||||
it++;
|
||||
CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
|
||||
}
|
||||
|
||||
SECTION("number")
|
||||
{
|
||||
json j(17);
|
||||
json::iterator it = j.begin();
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 0));
|
||||
it++;
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 1));
|
||||
it++;
|
||||
CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j({{"foo", "bar"}});
|
||||
json::iterator it = j.begin();
|
||||
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin()));
|
||||
it++;
|
||||
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end()));
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j({1, 2, 3, 4});
|
||||
json::iterator it = j.begin();
|
||||
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin()));
|
||||
it++;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
it++;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
it++;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
it++;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end()));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("pre-increment")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j(json::value_t::null);
|
||||
json::iterator it = j.begin();
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 1));
|
||||
++it;
|
||||
CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
|
||||
}
|
||||
|
||||
SECTION("number")
|
||||
{
|
||||
json j(17);
|
||||
json::iterator it = j.begin();
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 0));
|
||||
++it;
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 1));
|
||||
++it;
|
||||
CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j({{"foo", "bar"}});
|
||||
json::iterator it = j.begin();
|
||||
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin()));
|
||||
++it;
|
||||
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end()));
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j({1, 2, 3, 4});
|
||||
json::iterator it = j.begin();
|
||||
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin()));
|
||||
++it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
++it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
++it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
++it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end()));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("post-decrement")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j(json::value_t::null);
|
||||
json::iterator it = j.end();
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 1));
|
||||
}
|
||||
|
||||
SECTION("number")
|
||||
{
|
||||
json j(17);
|
||||
json::iterator it = j.end();
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 1));
|
||||
it--;
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 0));
|
||||
it--;
|
||||
CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j({{"foo", "bar"}});
|
||||
json::iterator it = j.end();
|
||||
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end()));
|
||||
it--;
|
||||
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin()));
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j({1, 2, 3, 4});
|
||||
json::iterator it = j.end();
|
||||
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end()));
|
||||
it--;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
it--;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
it--;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
it--;
|
||||
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("pre-decrement")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j(json::value_t::null);
|
||||
json::iterator it = j.end();
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 1));
|
||||
}
|
||||
|
||||
SECTION("number")
|
||||
{
|
||||
json j(17);
|
||||
json::iterator it = j.end();
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 1));
|
||||
--it;
|
||||
CHECK((it.m_it.primitive_iterator.m_it == 0));
|
||||
--it;
|
||||
CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j({{"foo", "bar"}});
|
||||
json::iterator it = j.end();
|
||||
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end()));
|
||||
--it;
|
||||
CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin()));
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j({1, 2, 3, 4});
|
||||
json::iterator it = j.end();
|
||||
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end()));
|
||||
--it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
--it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
--it;
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
--it;
|
||||
CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin()));
|
||||
CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
247
vendor/json/test/src/unit-class_lexer.cpp
vendored
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#define JSON_TESTS_PRIVATE
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
namespace
|
||||
{
|
||||
// shortcut to scan a string literal
|
||||
json::lexer::token_type scan_string(const char* s, const bool ignore_comments = false);
|
||||
json::lexer::token_type scan_string(const char* s, const bool ignore_comments)
|
||||
{
|
||||
auto ia = nlohmann::detail::input_adapter(s);
|
||||
return nlohmann::detail::lexer<json, decltype(ia)>(std::move(ia), ignore_comments).scan();
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_error_message(const char* s, const bool ignore_comments = false);
|
||||
std::string get_error_message(const char* s, const bool ignore_comments)
|
||||
{
|
||||
auto ia = nlohmann::detail::input_adapter(s);
|
||||
auto lexer = nlohmann::detail::lexer<json, decltype(ia)>(std::move(ia), ignore_comments);
|
||||
lexer.scan();
|
||||
return lexer.get_error_message();
|
||||
}
|
||||
|
||||
TEST_CASE("lexer class")
|
||||
{
|
||||
SECTION("scan")
|
||||
{
|
||||
SECTION("structural characters")
|
||||
{
|
||||
CHECK((scan_string("[") == json::lexer::token_type::begin_array));
|
||||
CHECK((scan_string("]") == json::lexer::token_type::end_array));
|
||||
CHECK((scan_string("{") == json::lexer::token_type::begin_object));
|
||||
CHECK((scan_string("}") == json::lexer::token_type::end_object));
|
||||
CHECK((scan_string(",") == json::lexer::token_type::value_separator));
|
||||
CHECK((scan_string(":") == json::lexer::token_type::name_separator));
|
||||
}
|
||||
|
||||
SECTION("literal names")
|
||||
{
|
||||
CHECK((scan_string("null") == json::lexer::token_type::literal_null));
|
||||
CHECK((scan_string("true") == json::lexer::token_type::literal_true));
|
||||
CHECK((scan_string("false") == json::lexer::token_type::literal_false));
|
||||
}
|
||||
|
||||
SECTION("numbers")
|
||||
{
|
||||
CHECK((scan_string("0") == json::lexer::token_type::value_unsigned));
|
||||
CHECK((scan_string("1") == json::lexer::token_type::value_unsigned));
|
||||
CHECK((scan_string("2") == json::lexer::token_type::value_unsigned));
|
||||
CHECK((scan_string("3") == json::lexer::token_type::value_unsigned));
|
||||
CHECK((scan_string("4") == json::lexer::token_type::value_unsigned));
|
||||
CHECK((scan_string("5") == json::lexer::token_type::value_unsigned));
|
||||
CHECK((scan_string("6") == json::lexer::token_type::value_unsigned));
|
||||
CHECK((scan_string("7") == json::lexer::token_type::value_unsigned));
|
||||
CHECK((scan_string("8") == json::lexer::token_type::value_unsigned));
|
||||
CHECK((scan_string("9") == json::lexer::token_type::value_unsigned));
|
||||
|
||||
CHECK((scan_string("-0") == json::lexer::token_type::value_integer));
|
||||
CHECK((scan_string("-1") == json::lexer::token_type::value_integer));
|
||||
|
||||
CHECK((scan_string("1.1") == json::lexer::token_type::value_float));
|
||||
CHECK((scan_string("-1.1") == json::lexer::token_type::value_float));
|
||||
CHECK((scan_string("1E10") == json::lexer::token_type::value_float));
|
||||
}
|
||||
|
||||
SECTION("whitespace")
|
||||
{
|
||||
// result is end_of_input, because not token is following
|
||||
CHECK((scan_string(" ") == json::lexer::token_type::end_of_input));
|
||||
CHECK((scan_string("\t") == json::lexer::token_type::end_of_input));
|
||||
CHECK((scan_string("\n") == json::lexer::token_type::end_of_input));
|
||||
CHECK((scan_string("\r") == json::lexer::token_type::end_of_input));
|
||||
CHECK((scan_string(" \t\n\r\n\t ") == json::lexer::token_type::end_of_input));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("token_type_name")
|
||||
{
|
||||
CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::uninitialized)) == "<uninitialized>"));
|
||||
CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::literal_true)) == "true literal"));
|
||||
CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::literal_false)) == "false literal"));
|
||||
CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::literal_null)) == "null literal"));
|
||||
CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::value_string)) == "string literal"));
|
||||
CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::value_unsigned)) == "number literal"));
|
||||
CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::value_integer)) == "number literal"));
|
||||
CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::value_float)) == "number literal"));
|
||||
CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::begin_array)) == "'['"));
|
||||
CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::begin_object)) == "'{'"));
|
||||
CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::end_array)) == "']'"));
|
||||
CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::end_object)) == "'}'"));
|
||||
CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::name_separator)) == "':'"));
|
||||
CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::value_separator)) == "','"));
|
||||
CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::parse_error)) == "<parse error>"));
|
||||
CHECK((std::string(json::lexer::token_type_name(json::lexer::token_type::end_of_input)) == "end of input"));
|
||||
}
|
||||
|
||||
SECTION("parse errors on first character")
|
||||
{
|
||||
for (int c = 1; c < 128; ++c)
|
||||
{
|
||||
// create string from the ASCII code
|
||||
const auto s = std::string(1, static_cast<char>(c));
|
||||
// store scan() result
|
||||
const auto res = scan_string(s.c_str());
|
||||
|
||||
CAPTURE(s)
|
||||
|
||||
switch (c)
|
||||
{
|
||||
// single characters that are valid tokens
|
||||
case ('['):
|
||||
case (']'):
|
||||
case ('{'):
|
||||
case ('}'):
|
||||
case (','):
|
||||
case (':'):
|
||||
case ('0'):
|
||||
case ('1'):
|
||||
case ('2'):
|
||||
case ('3'):
|
||||
case ('4'):
|
||||
case ('5'):
|
||||
case ('6'):
|
||||
case ('7'):
|
||||
case ('8'):
|
||||
case ('9'):
|
||||
{
|
||||
CHECK((res != json::lexer::token_type::parse_error));
|
||||
break;
|
||||
}
|
||||
|
||||
// whitespace
|
||||
case (' '):
|
||||
case ('\t'):
|
||||
case ('\n'):
|
||||
case ('\r'):
|
||||
{
|
||||
CHECK((res == json::lexer::token_type::end_of_input));
|
||||
break;
|
||||
}
|
||||
|
||||
// anything else is not expected
|
||||
default:
|
||||
{
|
||||
CHECK((res == json::lexer::token_type::parse_error));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("very large string")
|
||||
{
|
||||
// strings larger than 1024 bytes yield a resize of the lexer's yytext buffer
|
||||
std::string s("\"");
|
||||
s += std::string(2048, 'x');
|
||||
s += "\"";
|
||||
CHECK((scan_string(s.c_str()) == json::lexer::token_type::value_string));
|
||||
}
|
||||
|
||||
SECTION("fail on comments")
|
||||
{
|
||||
CHECK((scan_string("/", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/", false) == "invalid literal");
|
||||
|
||||
CHECK((scan_string("/!", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/!", false) == "invalid literal");
|
||||
CHECK((scan_string("/*", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/*", false) == "invalid literal");
|
||||
CHECK((scan_string("/**", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/**", false) == "invalid literal");
|
||||
|
||||
CHECK((scan_string("//", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("//", false) == "invalid literal");
|
||||
CHECK((scan_string("/**/", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/**/", false) == "invalid literal");
|
||||
CHECK((scan_string("/** /", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/** /", false) == "invalid literal");
|
||||
|
||||
CHECK((scan_string("/***/", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/***/", false) == "invalid literal");
|
||||
CHECK((scan_string("/* true */", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/* true */", false) == "invalid literal");
|
||||
CHECK((scan_string("/*/**/", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/*/**/", false) == "invalid literal");
|
||||
CHECK((scan_string("/*/* */", false) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/*/* */", false) == "invalid literal");
|
||||
}
|
||||
|
||||
SECTION("ignore comments")
|
||||
{
|
||||
CHECK((scan_string("/", true) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/", true) == "invalid comment; expecting '/' or '*' after '/'");
|
||||
|
||||
CHECK((scan_string("/!", true) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/!", true) == "invalid comment; expecting '/' or '*' after '/'");
|
||||
CHECK((scan_string("/*", true) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/*", true) == "invalid comment; missing closing '*/'");
|
||||
CHECK((scan_string("/**", true) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/**", true) == "invalid comment; missing closing '*/'");
|
||||
|
||||
CHECK((scan_string("//", true) == json::lexer::token_type::end_of_input));
|
||||
CHECK((scan_string("/**/", true) == json::lexer::token_type::end_of_input));
|
||||
CHECK((scan_string("/** /", true) == json::lexer::token_type::parse_error));
|
||||
CHECK(get_error_message("/** /", true) == "invalid comment; missing closing '*/'");
|
||||
|
||||
CHECK((scan_string("/***/", true) == json::lexer::token_type::end_of_input));
|
||||
CHECK((scan_string("/* true */", true) == json::lexer::token_type::end_of_input));
|
||||
CHECK((scan_string("/*/**/", true) == json::lexer::token_type::end_of_input));
|
||||
CHECK((scan_string("/*/* */", true) == json::lexer::token_type::end_of_input));
|
||||
|
||||
CHECK((scan_string("//\n//\n", true) == json::lexer::token_type::end_of_input));
|
||||
CHECK((scan_string("/**//**//**/", true) == json::lexer::token_type::end_of_input));
|
||||
}
|
||||
}
|
||||
1886
vendor/json/test/src/unit-class_parser.cpp
vendored
Normal file
270
vendor/json/test/src/unit-comparison.cpp
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
namespace
|
||||
{
|
||||
// helper function to check std::less<json::value_t>
|
||||
// see https://en.cppreference.com/w/cpp/utility/functional/less
|
||||
template <typename A, typename B, typename U = std::less<json::value_t>>
|
||||
bool f(A a, B b, U u = U())
|
||||
{
|
||||
return u(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("lexicographical comparison operators")
|
||||
{
|
||||
SECTION("types")
|
||||
{
|
||||
std::vector<json::value_t> j_types =
|
||||
{
|
||||
json::value_t::null,
|
||||
json::value_t::boolean,
|
||||
json::value_t::number_integer,
|
||||
json::value_t::number_unsigned,
|
||||
json::value_t::number_float,
|
||||
json::value_t::object,
|
||||
json::value_t::array,
|
||||
json::value_t::string,
|
||||
json::value_t::binary
|
||||
};
|
||||
|
||||
SECTION("comparison: less")
|
||||
{
|
||||
std::vector<std::vector<bool>> expected =
|
||||
{
|
||||
{false, true, true, true, true, true, true, true, true},
|
||||
{false, false, true, true, true, true, true, true, true},
|
||||
{false, false, false, false, false, true, true, true, true},
|
||||
{false, false, false, false, false, true, true, true, true},
|
||||
{false, false, false, false, false, true, true, true, true},
|
||||
{false, false, false, false, false, false, true, true, true},
|
||||
{false, false, false, false, false, false, false, true, true},
|
||||
{false, false, false, false, false, false, false, false, true},
|
||||
{false, false, false, false, false, false, false, false, false}
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < j_types.size(); ++i)
|
||||
{
|
||||
for (size_t j = 0; j < j_types.size(); ++j)
|
||||
{
|
||||
CAPTURE(i)
|
||||
CAPTURE(j)
|
||||
// check precomputed values
|
||||
CHECK(operator<(j_types[i], j_types[j]) == expected[i][j]);
|
||||
CHECK(f(j_types[i], j_types[j]) == expected[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("values")
|
||||
{
|
||||
json j_values =
|
||||
{
|
||||
nullptr, nullptr,
|
||||
-17, 42,
|
||||
8u, 13u,
|
||||
3.14159, 23.42,
|
||||
"foo", "bar",
|
||||
true, false,
|
||||
{1, 2, 3}, {"one", "two", "three"},
|
||||
{{"first", 1}, {"second", 2}}, {{"a", "A"}, {"b", {"B"}}},
|
||||
json::binary({1, 2, 3}), json::binary({1, 2, 4})
|
||||
};
|
||||
|
||||
SECTION("comparison: equal")
|
||||
{
|
||||
std::vector<std::vector<bool>> expected =
|
||||
{
|
||||
{true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false},
|
||||
{true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false},
|
||||
{false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false},
|
||||
{false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false},
|
||||
{false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false},
|
||||
{false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false},
|
||||
{false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false},
|
||||
{false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false},
|
||||
{false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false},
|
||||
{false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false},
|
||||
{false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false},
|
||||
{false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false},
|
||||
{false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false},
|
||||
{false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false},
|
||||
{false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false},
|
||||
{false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false},
|
||||
{false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false},
|
||||
{false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true}
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < j_values.size(); ++i)
|
||||
{
|
||||
for (size_t j = 0; j < j_values.size(); ++j)
|
||||
{
|
||||
CAPTURE(i)
|
||||
CAPTURE(j)
|
||||
CAPTURE(j_values[i])
|
||||
CAPTURE(j_values[j])
|
||||
// check precomputed values
|
||||
CHECK( (j_values[i] == j_values[j]) == expected[i][j] );
|
||||
}
|
||||
}
|
||||
|
||||
// comparison with discarded elements
|
||||
json j_discarded(json::value_t::discarded);
|
||||
for (size_t i = 0; i < j_values.size(); ++i)
|
||||
{
|
||||
CHECK( (j_values[i] == j_discarded) == false);
|
||||
CHECK( (j_discarded == j_values[i]) == false);
|
||||
CHECK( (j_discarded == j_discarded) == false);
|
||||
}
|
||||
|
||||
// compare with null pointer
|
||||
json j_null;
|
||||
CHECK(j_null == nullptr);
|
||||
CHECK(nullptr == j_null);
|
||||
}
|
||||
|
||||
SECTION("comparison: not equal")
|
||||
{
|
||||
for (size_t i = 0; i < j_values.size(); ++i)
|
||||
{
|
||||
for (size_t j = 0; j < j_values.size(); ++j)
|
||||
{
|
||||
CAPTURE(i)
|
||||
CAPTURE(j)
|
||||
// check definition
|
||||
CHECK( (j_values[i] != j_values[j]) == !(j_values[i] == j_values[j]) );
|
||||
}
|
||||
}
|
||||
|
||||
// compare with null pointer
|
||||
json j_null;
|
||||
CHECK( (j_null != nullptr) == false);
|
||||
CHECK( (nullptr != j_null) == false);
|
||||
CHECK( (j_null != nullptr) == !(j_null == nullptr));
|
||||
CHECK( (nullptr != j_null) == !(nullptr == j_null));
|
||||
}
|
||||
|
||||
SECTION("comparison: less")
|
||||
{
|
||||
std::vector<std::vector<bool>> expected =
|
||||
{
|
||||
{false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true},
|
||||
{false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true},
|
||||
{false, false, false, true, true, true, true, true, true, true, false, false, true, true, true, true, true, true},
|
||||
{false, false, false, false, false, false, false, false, true, true, false, false, true, true, true, true, true, true},
|
||||
{false, false, false, true, false, true, false, true, true, true, false, false, true, true, true, true, true, true},
|
||||
{false, false, false, true, false, false, false, true, true, true, false, false, true, true, true, true, true, true},
|
||||
{false, false, false, true, true, true, false, true, true, true, false, false, true, true, true, true, true, true},
|
||||
{false, false, false, true, false, false, false, false, true, true, false, false, true, true, true, true, true, true},
|
||||
{false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true},
|
||||
{false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, true, true},
|
||||
{false, false, true, true, true, true, true, true, true, true, false, false, true, true, true, true, true, true},
|
||||
{false, false, true, true, true, true, true, true, true, true, true, false, true, true, true, true, true, true},
|
||||
{false, false, false, false, false, false, false, false, true, true, false, false, false, true, false, false, true, true},
|
||||
{false, false, false, false, false, false, false, false, true, true, false, false, false, false, false, false, true, true},
|
||||
{false, false, false, false, false, false, false, false, true, true, false, false, true, true, false, false, true, true},
|
||||
{false, false, false, false, false, false, false, false, true, true, false, false, true, true, true, false, true, true},
|
||||
{false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true},
|
||||
{false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < j_values.size(); ++i)
|
||||
{
|
||||
for (size_t j = 0; j < j_values.size(); ++j)
|
||||
{
|
||||
CAPTURE(i)
|
||||
CAPTURE(j)
|
||||
CAPTURE(j_values[i])
|
||||
CAPTURE(j_values[j])
|
||||
// check precomputed values
|
||||
CHECK( (j_values[i] < j_values[j]) == expected[i][j] );
|
||||
}
|
||||
}
|
||||
|
||||
// comparison with discarded elements
|
||||
json j_discarded(json::value_t::discarded);
|
||||
for (size_t i = 0; i < j_values.size(); ++i)
|
||||
{
|
||||
CAPTURE(i)
|
||||
CHECK( (j_values[i] < j_discarded) == false);
|
||||
CHECK( (j_discarded < j_values[i]) == false);
|
||||
CHECK( (j_discarded < j_discarded) == false);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("comparison: less than or equal equal")
|
||||
{
|
||||
for (size_t i = 0; i < j_values.size(); ++i)
|
||||
{
|
||||
for (size_t j = 0; j < j_values.size(); ++j)
|
||||
{
|
||||
CAPTURE(i)
|
||||
CAPTURE(j)
|
||||
// check definition
|
||||
CHECK( (j_values[i] <= j_values[j]) == !(j_values[j] < j_values[i]) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("comparison: greater than")
|
||||
{
|
||||
for (size_t i = 0; i < j_values.size(); ++i)
|
||||
{
|
||||
for (size_t j = 0; j < j_values.size(); ++j)
|
||||
{
|
||||
CAPTURE(i)
|
||||
CAPTURE(j)
|
||||
// check definition
|
||||
CHECK( (j_values[i] > j_values[j]) == (j_values[j] < j_values[i]) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("comparison: greater than or equal")
|
||||
{
|
||||
for (size_t i = 0; i < j_values.size(); ++i)
|
||||
{
|
||||
for (size_t j = 0; j < j_values.size(); ++j)
|
||||
{
|
||||
CAPTURE(i)
|
||||
CAPTURE(j)
|
||||
// check definition
|
||||
CHECK( (j_values[i] >= j_values[j]) == !(j_values[i] < j_values[j]) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
171
vendor/json/test/src/unit-concepts.cpp
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
TEST_CASE("concepts")
|
||||
{
|
||||
SECTION("container requirements for json")
|
||||
{
|
||||
// X: container class: json
|
||||
// T: type of objects: json
|
||||
// a, b: values of type X: json
|
||||
|
||||
// TABLE 96 - Container Requirements
|
||||
|
||||
// X::value_type must return T
|
||||
CHECK((std::is_same<json::value_type, json>::value));
|
||||
|
||||
// X::reference must return lvalue of T
|
||||
CHECK((std::is_same<json::reference, json&>::value));
|
||||
|
||||
// X::const_reference must return const lvalue of T
|
||||
CHECK((std::is_same<json::const_reference, const json&>::value));
|
||||
|
||||
// X::iterator must return iterator whose value_type is T
|
||||
CHECK((std::is_same<json::iterator::value_type, json>::value));
|
||||
// X::iterator must meet the forward iterator requirements
|
||||
CHECK((std::is_base_of<std::forward_iterator_tag, typename std::iterator_traits<json::iterator>::iterator_category>::value));
|
||||
// X::iterator must be convertible to X::const_iterator
|
||||
CHECK((std::is_convertible<json::iterator, json::const_iterator>::value));
|
||||
|
||||
// X::const_iterator must return iterator whose value_type is T
|
||||
CHECK((std::is_same<json::const_iterator::value_type, json>::value));
|
||||
// X::const_iterator must meet the forward iterator requirements
|
||||
CHECK((std::is_base_of<std::forward_iterator_tag, typename std::iterator_traits<json::const_iterator>::iterator_category>::value));
|
||||
|
||||
// X::difference_type must return a signed integer
|
||||
CHECK((std::is_signed<json::difference_type>::value));
|
||||
// X::difference_type must be identical to X::iterator::difference_type
|
||||
CHECK((std::is_same<json::difference_type, json::iterator::difference_type>::value));
|
||||
// X::difference_type must be identical to X::const_iterator::difference_type
|
||||
CHECK((std::is_same<json::difference_type, json::const_iterator::difference_type>::value));
|
||||
|
||||
// X::size_type must return an unsigned integer
|
||||
CHECK((std::is_unsigned<json::size_type>::value));
|
||||
// X::size_type can represent any non-negative value of X::difference_type
|
||||
CHECK(static_cast<json::size_type>((std::numeric_limits<json::difference_type>::max)()) <=
|
||||
(std::numeric_limits<json::size_type>::max)());
|
||||
|
||||
// the expression "X u" has the post-condition "u.empty()"
|
||||
{
|
||||
json u;
|
||||
CHECK(u.empty());
|
||||
}
|
||||
|
||||
// the expression "X()" has the post-condition "X().empty()"
|
||||
CHECK(json().empty());
|
||||
}
|
||||
|
||||
SECTION("class json")
|
||||
{
|
||||
SECTION("DefaultConstructible")
|
||||
{
|
||||
CHECK(std::is_nothrow_default_constructible<json>::value);
|
||||
}
|
||||
|
||||
SECTION("MoveConstructible")
|
||||
{
|
||||
CHECK(std::is_move_constructible<json>::value);
|
||||
CHECK(std::is_nothrow_move_constructible<json>::value);
|
||||
}
|
||||
|
||||
SECTION("CopyConstructible")
|
||||
{
|
||||
CHECK(std::is_copy_constructible<json>::value);
|
||||
}
|
||||
|
||||
SECTION("MoveAssignable")
|
||||
{
|
||||
CHECK(std::is_nothrow_move_assignable<json>::value);
|
||||
}
|
||||
|
||||
SECTION("CopyAssignable")
|
||||
{
|
||||
CHECK(std::is_copy_assignable<json>::value);
|
||||
}
|
||||
|
||||
SECTION("Destructible")
|
||||
{
|
||||
CHECK(std::is_nothrow_destructible<json>::value);
|
||||
}
|
||||
|
||||
SECTION("StandardLayoutType")
|
||||
{
|
||||
CHECK(std::is_standard_layout<json>::value);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("class iterator")
|
||||
{
|
||||
SECTION("CopyConstructible")
|
||||
{
|
||||
CHECK(std::is_nothrow_copy_constructible<json::iterator>::value);
|
||||
CHECK(std::is_nothrow_copy_constructible<json::const_iterator>::value);
|
||||
}
|
||||
|
||||
SECTION("CopyAssignable")
|
||||
{
|
||||
// STL iterators used by json::iterator don't pass this test in Debug mode
|
||||
#if !defined(_MSC_VER) || (_ITERATOR_DEBUG_LEVEL == 0)
|
||||
CHECK(std::is_nothrow_copy_assignable<json::iterator>::value);
|
||||
CHECK(std::is_nothrow_copy_assignable<json::const_iterator>::value);
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("Destructible")
|
||||
{
|
||||
CHECK(std::is_nothrow_destructible<json::iterator>::value);
|
||||
CHECK(std::is_nothrow_destructible<json::const_iterator>::value);
|
||||
}
|
||||
|
||||
SECTION("Swappable")
|
||||
{
|
||||
{
|
||||
json j {1, 2, 3};
|
||||
json::iterator it1 = j.begin();
|
||||
json::iterator it2 = j.end();
|
||||
swap(it1, it2);
|
||||
CHECK(it1 == j.end());
|
||||
CHECK(it2 == j.begin());
|
||||
}
|
||||
{
|
||||
json j {1, 2, 3};
|
||||
json::const_iterator it1 = j.cbegin();
|
||||
json::const_iterator it2 = j.cend();
|
||||
swap(it1, it2);
|
||||
CHECK(it1 == j.end());
|
||||
CHECK(it2 == j.begin());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1590
vendor/json/test/src/unit-constructor1.cpp
vendored
Normal file
207
vendor/json/test/src/unit-constructor2.cpp
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
TEST_CASE("other constructors and destructor")
|
||||
{
|
||||
SECTION("copy constructor")
|
||||
{
|
||||
SECTION("object")
|
||||
{
|
||||
json j {{"foo", 1}, {"bar", false}};
|
||||
json k(j);
|
||||
CHECK(j == k);
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j {"foo", 1, 42.23, false};
|
||||
json k(j);
|
||||
CHECK(j == k);
|
||||
}
|
||||
|
||||
SECTION("null")
|
||||
{
|
||||
json j(nullptr);
|
||||
json k(j);
|
||||
CHECK(j == k);
|
||||
}
|
||||
|
||||
SECTION("boolean")
|
||||
{
|
||||
json j(true);
|
||||
json k(j);
|
||||
CHECK(j == k);
|
||||
}
|
||||
|
||||
SECTION("string")
|
||||
{
|
||||
json j("Hello world");
|
||||
json k(j);
|
||||
CHECK(j == k);
|
||||
}
|
||||
|
||||
SECTION("number (integer)")
|
||||
{
|
||||
json j(42);
|
||||
json k(j);
|
||||
CHECK(j == k);
|
||||
}
|
||||
|
||||
SECTION("number (unsigned)")
|
||||
{
|
||||
json j(42u);
|
||||
json k(j);
|
||||
CHECK(j == k);
|
||||
}
|
||||
|
||||
SECTION("number (floating-point)")
|
||||
{
|
||||
json j(42.23);
|
||||
json k(j);
|
||||
CHECK(j == k);
|
||||
}
|
||||
|
||||
SECTION("binary")
|
||||
{
|
||||
json j = json::binary({1, 2, 3});
|
||||
json k(j);
|
||||
CHECK(j == k);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("move constructor")
|
||||
{
|
||||
json j {{"foo", "bar"}, {"baz", {1, 2, 3, 4}}, {"a", 42u}, {"b", 42.23}, {"c", nullptr}};
|
||||
CHECK(j.type() == json::value_t::object);
|
||||
json k(std::move(j));
|
||||
CHECK(k.type() == json::value_t::object);
|
||||
CHECK(j.type() == json::value_t::null);
|
||||
}
|
||||
|
||||
SECTION("copy assignment")
|
||||
{
|
||||
SECTION("object")
|
||||
{
|
||||
json j {{"foo", 1}, {"bar", false}};
|
||||
json k;
|
||||
k = j;
|
||||
CHECK(j == k);
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j {"foo", 1, 42.23, false};
|
||||
json k;
|
||||
k = j;
|
||||
CHECK(j == k);
|
||||
}
|
||||
|
||||
SECTION("null")
|
||||
{
|
||||
json j(nullptr);
|
||||
json k;
|
||||
k = j;
|
||||
CHECK(j == k);
|
||||
}
|
||||
|
||||
SECTION("boolean")
|
||||
{
|
||||
json j(true);
|
||||
json k;
|
||||
k = j;
|
||||
CHECK(j == k);
|
||||
}
|
||||
|
||||
SECTION("string")
|
||||
{
|
||||
json j("Hello world");
|
||||
json k;
|
||||
k = j;
|
||||
CHECK(j == k);
|
||||
}
|
||||
|
||||
SECTION("number (integer)")
|
||||
{
|
||||
json j(42);
|
||||
json k;
|
||||
k = j;
|
||||
CHECK(j == k);
|
||||
}
|
||||
|
||||
SECTION("number (unsigned)")
|
||||
{
|
||||
json j(42u);
|
||||
json k;
|
||||
k = j;
|
||||
CHECK(j == k);
|
||||
}
|
||||
|
||||
SECTION("number (floating-point)")
|
||||
{
|
||||
json j(42.23);
|
||||
json k;
|
||||
k = j;
|
||||
CHECK(j == k);
|
||||
}
|
||||
|
||||
SECTION("binary")
|
||||
{
|
||||
json j = json::binary({1, 2, 3});
|
||||
json k;
|
||||
k = j;
|
||||
CHECK(j == k);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("destructor")
|
||||
{
|
||||
SECTION("object")
|
||||
{
|
||||
auto j = new json {{"foo", 1}, {"bar", false}};
|
||||
delete j;
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
auto j = new json {"foo", 1, 1u, false, 23.42};
|
||||
delete j;
|
||||
}
|
||||
|
||||
SECTION("string")
|
||||
{
|
||||
auto j = new json("Hello world");
|
||||
delete j;
|
||||
}
|
||||
}
|
||||
}
|
||||
117
vendor/json/test/src/unit-convenience.cpp
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#define JSON_TESTS_PRIVATE
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace
|
||||
{
|
||||
void check_escaped(const char* original, const char* escaped = "", const bool ensure_ascii = false);
|
||||
void check_escaped(const char* original, const char* escaped, const bool ensure_ascii)
|
||||
{
|
||||
std::stringstream ss;
|
||||
json::serializer s(nlohmann::detail::output_adapter<char>(ss), ' ');
|
||||
s.dump_escaped(original, ensure_ascii);
|
||||
CHECK(ss.str() == escaped);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("convenience functions")
|
||||
{
|
||||
SECTION("type name as string")
|
||||
{
|
||||
CHECK(std::string(json(json::value_t::null).type_name()) == "null");
|
||||
CHECK(std::string(json(json::value_t::object).type_name()) == "object");
|
||||
CHECK(std::string(json(json::value_t::array).type_name()) == "array");
|
||||
CHECK(std::string(json(json::value_t::number_integer).type_name()) == "number");
|
||||
CHECK(std::string(json(json::value_t::number_unsigned).type_name()) == "number");
|
||||
CHECK(std::string(json(json::value_t::number_float).type_name()) == "number");
|
||||
CHECK(std::string(json(json::value_t::binary).type_name()) == "binary");
|
||||
CHECK(std::string(json(json::value_t::boolean).type_name()) == "boolean");
|
||||
CHECK(std::string(json(json::value_t::string).type_name()) == "string");
|
||||
CHECK(std::string(json(json::value_t::discarded).type_name()) == "discarded");
|
||||
}
|
||||
|
||||
SECTION("string escape")
|
||||
{
|
||||
check_escaped("\"", "\\\"");
|
||||
check_escaped("\\", "\\\\");
|
||||
check_escaped("\b", "\\b");
|
||||
check_escaped("\f", "\\f");
|
||||
check_escaped("\n", "\\n");
|
||||
check_escaped("\r", "\\r");
|
||||
check_escaped("\t", "\\t");
|
||||
|
||||
check_escaped("\x01", "\\u0001");
|
||||
check_escaped("\x02", "\\u0002");
|
||||
check_escaped("\x03", "\\u0003");
|
||||
check_escaped("\x04", "\\u0004");
|
||||
check_escaped("\x05", "\\u0005");
|
||||
check_escaped("\x06", "\\u0006");
|
||||
check_escaped("\x07", "\\u0007");
|
||||
check_escaped("\x08", "\\b");
|
||||
check_escaped("\x09", "\\t");
|
||||
check_escaped("\x0a", "\\n");
|
||||
check_escaped("\x0b", "\\u000b");
|
||||
check_escaped("\x0c", "\\f");
|
||||
check_escaped("\x0d", "\\r");
|
||||
check_escaped("\x0e", "\\u000e");
|
||||
check_escaped("\x0f", "\\u000f");
|
||||
check_escaped("\x10", "\\u0010");
|
||||
check_escaped("\x11", "\\u0011");
|
||||
check_escaped("\x12", "\\u0012");
|
||||
check_escaped("\x13", "\\u0013");
|
||||
check_escaped("\x14", "\\u0014");
|
||||
check_escaped("\x15", "\\u0015");
|
||||
check_escaped("\x16", "\\u0016");
|
||||
check_escaped("\x17", "\\u0017");
|
||||
check_escaped("\x18", "\\u0018");
|
||||
check_escaped("\x19", "\\u0019");
|
||||
check_escaped("\x1a", "\\u001a");
|
||||
check_escaped("\x1b", "\\u001b");
|
||||
check_escaped("\x1c", "\\u001c");
|
||||
check_escaped("\x1d", "\\u001d");
|
||||
check_escaped("\x1e", "\\u001e");
|
||||
check_escaped("\x1f", "\\u001f");
|
||||
|
||||
// invalid UTF-8 characters
|
||||
CHECK_THROWS_AS(check_escaped("ä\xA9ü"), json::type_error&);
|
||||
CHECK_THROWS_WITH(check_escaped("ä\xA9ü"),
|
||||
"[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9");
|
||||
|
||||
CHECK_THROWS_AS(check_escaped("\xC2"), json::type_error&);
|
||||
CHECK_THROWS_WITH(check_escaped("\xC2"),
|
||||
"[json.exception.type_error.316] incomplete UTF-8 string; last byte: 0xC2");
|
||||
}
|
||||
}
|
||||
1712
vendor/json/test/src/unit-conversions.cpp
vendored
Normal file
1114
vendor/json/test/src/unit-deserialization.cpp
vendored
Normal file
111
vendor/json/test/src/unit-diagnostics.cpp
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#ifdef JSON_DIAGNOSTICS
|
||||
#undef JSON_DIAGNOSTICS
|
||||
#endif
|
||||
|
||||
#define JSON_DIAGNOSTICS 1
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
TEST_CASE("Better diagnostics")
|
||||
{
|
||||
SECTION("empty JSON Pointer")
|
||||
{
|
||||
json j = 1;
|
||||
std::string s;
|
||||
CHECK_THROWS_WITH_AS(s = j.get<std::string>(), "[json.exception.type_error.302] type must be string, but is number", json::type_error);
|
||||
}
|
||||
|
||||
SECTION("invalid type")
|
||||
{
|
||||
json j;
|
||||
j["a"]["b"]["c"] = 1;
|
||||
std::string s;
|
||||
CHECK_THROWS_WITH_AS(s = j["a"]["b"]["c"].get<std::string>(), "[json.exception.type_error.302] (/a/b/c) type must be string, but is number", json::type_error);
|
||||
}
|
||||
|
||||
SECTION("missing key")
|
||||
{
|
||||
json j;
|
||||
j["object"]["object"] = true;
|
||||
CHECK_THROWS_WITH_AS(j["object"].at("not_found"), "[json.exception.out_of_range.403] (/object) key 'not_found' not found", json::out_of_range);
|
||||
}
|
||||
|
||||
SECTION("array index out of range")
|
||||
{
|
||||
json j;
|
||||
j["array"][4] = true;
|
||||
CHECK_THROWS_WITH_AS(j["array"].at(5), "[json.exception.out_of_range.401] (/array) array index 5 is out of range", json::out_of_range);
|
||||
}
|
||||
|
||||
SECTION("array index at wrong type")
|
||||
{
|
||||
json j;
|
||||
j["array"][4] = true;
|
||||
CHECK_THROWS_WITH_AS(j["array"][4][5], "[json.exception.type_error.305] (/array/4) cannot use operator[] with a numeric argument with boolean", json::type_error);
|
||||
}
|
||||
|
||||
SECTION("wrong iterator")
|
||||
{
|
||||
json j;
|
||||
j["array"] = json::array();
|
||||
CHECK_THROWS_WITH_AS(j["array"].erase(j.begin()), "[json.exception.invalid_iterator.202] (/array) iterator does not fit current value", json::invalid_iterator);
|
||||
}
|
||||
|
||||
SECTION("JSON Pointer escaping")
|
||||
{
|
||||
json j;
|
||||
j["a/b"]["m~n"] = 1;
|
||||
std::string s;
|
||||
CHECK_THROWS_WITH_AS(s = j["a/b"]["m~n"].get<std::string>(), "[json.exception.type_error.302] (/a~1b/m~0n) type must be string, but is number", json::type_error);
|
||||
}
|
||||
|
||||
SECTION("Parse error")
|
||||
{
|
||||
CHECK_THROWS_WITH_AS(json::parse(""), "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error);
|
||||
}
|
||||
|
||||
SECTION("Regression test for https://github.com/nlohmann/json/pull/2562#pullrequestreview-574858448")
|
||||
{
|
||||
CHECK_THROWS_WITH_AS(json({"0", "0"})[1].get<int>(), "[json.exception.type_error.302] (/1) type must be number, but is string", json::type_error);
|
||||
CHECK_THROWS_WITH_AS(json({"0", "1"})[1].get<int>(), "[json.exception.type_error.302] (/1) type must be number, but is string", json::type_error);
|
||||
}
|
||||
|
||||
SECTION("Regression test for https://github.com/nlohmann/json/pull/2562/files/380a613f2b5d32425021129cd1f371ddcfd54ddf#r563259793")
|
||||
{
|
||||
json j;
|
||||
j["/foo"] = {1, 2, 3};
|
||||
CHECK_THROWS_WITH_AS(j.unflatten(), "[json.exception.type_error.315] (/~1foo) values in object must be primitive", json::type_error);
|
||||
}
|
||||
}
|
||||
1006
vendor/json/test/src/unit-element_access1.cpp
vendored
Normal file
1109
vendor/json/test/src/unit-element_access2.cpp
vendored
Normal file
84
vendor/json/test/src/unit-hash.cpp
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using json = nlohmann::json;
|
||||
|
||||
#include <set>
|
||||
|
||||
TEST_CASE("hash")
|
||||
{
|
||||
// Collect hashes for different JSON values and make sure that they are distinct
|
||||
// We cannot compare against fixed values, because the implementation of
|
||||
// std::hash may differ between compilers.
|
||||
|
||||
std::set<std::size_t> hashes;
|
||||
|
||||
// null
|
||||
hashes.insert(std::hash<json> {}(json(nullptr)));
|
||||
|
||||
// boolean
|
||||
hashes.insert(std::hash<json> {}(json(true)));
|
||||
hashes.insert(std::hash<json> {}(json(false)));
|
||||
|
||||
// string
|
||||
hashes.insert(std::hash<json> {}(json("")));
|
||||
hashes.insert(std::hash<json> {}(json("foo")));
|
||||
|
||||
// number
|
||||
hashes.insert(std::hash<json> {}(json(0)));
|
||||
hashes.insert(std::hash<json> {}(json(unsigned(0))));
|
||||
|
||||
hashes.insert(std::hash<json> {}(json(-1)));
|
||||
hashes.insert(std::hash<json> {}(json(0.0)));
|
||||
hashes.insert(std::hash<json> {}(json(42.23)));
|
||||
|
||||
// array
|
||||
hashes.insert(std::hash<json> {}(json::array()));
|
||||
hashes.insert(std::hash<json> {}(json::array({1, 2, 3})));
|
||||
|
||||
// object
|
||||
hashes.insert(std::hash<json> {}(json::object()));
|
||||
hashes.insert(std::hash<json> {}(json::object({{"foo", "bar"}})));
|
||||
|
||||
// binary
|
||||
hashes.insert(std::hash<json> {}(json::binary({})));
|
||||
hashes.insert(std::hash<json> {}(json::binary({}, 0)));
|
||||
hashes.insert(std::hash<json> {}(json::binary({}, 42)));
|
||||
hashes.insert(std::hash<json> {}(json::binary({1, 2, 3})));
|
||||
hashes.insert(std::hash<json> {}(json::binary({1, 2, 3}, 0)));
|
||||
hashes.insert(std::hash<json> {}(json::binary({1, 2, 3}, 42)));
|
||||
|
||||
// discarded
|
||||
hashes.insert(std::hash<json> {}(json(json::value_t::discarded)));
|
||||
|
||||
CHECK(hashes.size() == 21);
|
||||
}
|
||||
480
vendor/json/test/src/unit-inspection.cpp
vendored
Normal file
@@ -0,0 +1,480 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <test_data.hpp>
|
||||
|
||||
TEST_CASE("object inspection")
|
||||
{
|
||||
SECTION("convenience type checker")
|
||||
{
|
||||
SECTION("object")
|
||||
{
|
||||
json j {{"foo", 1}, {"bar", false}};
|
||||
CHECK(!j.is_null());
|
||||
CHECK(!j.is_boolean());
|
||||
CHECK(!j.is_number());
|
||||
CHECK(!j.is_number_integer());
|
||||
CHECK(!j.is_number_unsigned());
|
||||
CHECK(!j.is_number_float());
|
||||
CHECK(!j.is_binary());
|
||||
CHECK(j.is_object());
|
||||
CHECK(!j.is_array());
|
||||
CHECK(!j.is_string());
|
||||
CHECK(!j.is_discarded());
|
||||
CHECK(!j.is_primitive());
|
||||
CHECK(j.is_structured());
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j {"foo", 1, 1u, 42.23, false};
|
||||
CHECK(!j.is_null());
|
||||
CHECK(!j.is_boolean());
|
||||
CHECK(!j.is_number());
|
||||
CHECK(!j.is_number_integer());
|
||||
CHECK(!j.is_number_unsigned());
|
||||
CHECK(!j.is_number_float());
|
||||
CHECK(!j.is_binary());
|
||||
CHECK(!j.is_object());
|
||||
CHECK(j.is_array());
|
||||
CHECK(!j.is_string());
|
||||
CHECK(!j.is_discarded());
|
||||
CHECK(!j.is_primitive());
|
||||
CHECK(j.is_structured());
|
||||
}
|
||||
|
||||
SECTION("null")
|
||||
{
|
||||
json j(nullptr);
|
||||
CHECK(j.is_null());
|
||||
CHECK(!j.is_boolean());
|
||||
CHECK(!j.is_number());
|
||||
CHECK(!j.is_number_integer());
|
||||
CHECK(!j.is_number_unsigned());
|
||||
CHECK(!j.is_number_float());
|
||||
CHECK(!j.is_binary());
|
||||
CHECK(!j.is_object());
|
||||
CHECK(!j.is_array());
|
||||
CHECK(!j.is_string());
|
||||
CHECK(!j.is_discarded());
|
||||
CHECK(j.is_primitive());
|
||||
CHECK(!j.is_structured());
|
||||
}
|
||||
|
||||
SECTION("boolean")
|
||||
{
|
||||
json j(true);
|
||||
CHECK(!j.is_null());
|
||||
CHECK(j.is_boolean());
|
||||
CHECK(!j.is_number());
|
||||
CHECK(!j.is_number_integer());
|
||||
CHECK(!j.is_number_unsigned());
|
||||
CHECK(!j.is_number_float());
|
||||
CHECK(!j.is_binary());
|
||||
CHECK(!j.is_object());
|
||||
CHECK(!j.is_array());
|
||||
CHECK(!j.is_string());
|
||||
CHECK(!j.is_discarded());
|
||||
CHECK(j.is_primitive());
|
||||
CHECK(!j.is_structured());
|
||||
}
|
||||
|
||||
SECTION("string")
|
||||
{
|
||||
json j("Hello world");
|
||||
CHECK(!j.is_null());
|
||||
CHECK(!j.is_boolean());
|
||||
CHECK(!j.is_number());
|
||||
CHECK(!j.is_number_integer());
|
||||
CHECK(!j.is_number_unsigned());
|
||||
CHECK(!j.is_number_float());
|
||||
CHECK(!j.is_binary());
|
||||
CHECK(!j.is_object());
|
||||
CHECK(!j.is_array());
|
||||
CHECK(j.is_string());
|
||||
CHECK(!j.is_discarded());
|
||||
CHECK(j.is_primitive());
|
||||
CHECK(!j.is_structured());
|
||||
}
|
||||
|
||||
SECTION("number (integer)")
|
||||
{
|
||||
json j(42);
|
||||
CHECK(!j.is_null());
|
||||
CHECK(!j.is_boolean());
|
||||
CHECK(j.is_number());
|
||||
CHECK(j.is_number_integer());
|
||||
CHECK(!j.is_number_unsigned());
|
||||
CHECK(!j.is_number_float());
|
||||
CHECK(!j.is_binary());
|
||||
CHECK(!j.is_object());
|
||||
CHECK(!j.is_array());
|
||||
CHECK(!j.is_string());
|
||||
CHECK(!j.is_discarded());
|
||||
CHECK(j.is_primitive());
|
||||
CHECK(!j.is_structured());
|
||||
}
|
||||
|
||||
SECTION("number (unsigned)")
|
||||
{
|
||||
json j(42u);
|
||||
CHECK(!j.is_null());
|
||||
CHECK(!j.is_boolean());
|
||||
CHECK(j.is_number());
|
||||
CHECK(j.is_number_integer());
|
||||
CHECK(j.is_number_unsigned());
|
||||
CHECK(!j.is_number_float());
|
||||
CHECK(!j.is_binary());
|
||||
CHECK(!j.is_object());
|
||||
CHECK(!j.is_array());
|
||||
CHECK(!j.is_string());
|
||||
CHECK(!j.is_discarded());
|
||||
CHECK(j.is_primitive());
|
||||
CHECK(!j.is_structured());
|
||||
}
|
||||
|
||||
SECTION("number (floating-point)")
|
||||
{
|
||||
json j(42.23);
|
||||
CHECK(!j.is_null());
|
||||
CHECK(!j.is_boolean());
|
||||
CHECK(j.is_number());
|
||||
CHECK(!j.is_number_integer());
|
||||
CHECK(!j.is_number_unsigned());
|
||||
CHECK(j.is_number_float());
|
||||
CHECK(!j.is_binary());
|
||||
CHECK(!j.is_object());
|
||||
CHECK(!j.is_array());
|
||||
CHECK(!j.is_string());
|
||||
CHECK(!j.is_discarded());
|
||||
CHECK(j.is_primitive());
|
||||
CHECK(!j.is_structured());
|
||||
}
|
||||
|
||||
SECTION("binary")
|
||||
{
|
||||
json j(json::value_t::binary);
|
||||
CHECK(!j.is_null());
|
||||
CHECK(!j.is_boolean());
|
||||
CHECK(!j.is_number());
|
||||
CHECK(!j.is_number_integer());
|
||||
CHECK(!j.is_number_unsigned());
|
||||
CHECK(!j.is_number_float());
|
||||
CHECK(j.is_binary());
|
||||
CHECK(!j.is_object());
|
||||
CHECK(!j.is_array());
|
||||
CHECK(!j.is_string());
|
||||
CHECK(!j.is_discarded());
|
||||
CHECK(j.is_primitive());
|
||||
CHECK(!j.is_structured());
|
||||
}
|
||||
|
||||
SECTION("discarded")
|
||||
{
|
||||
json j(json::value_t::discarded);
|
||||
CHECK(!j.is_null());
|
||||
CHECK(!j.is_boolean());
|
||||
CHECK(!j.is_number());
|
||||
CHECK(!j.is_number_integer());
|
||||
CHECK(!j.is_number_unsigned());
|
||||
CHECK(!j.is_number_float());
|
||||
CHECK(!j.is_binary());
|
||||
CHECK(!j.is_object());
|
||||
CHECK(!j.is_array());
|
||||
CHECK(!j.is_string());
|
||||
CHECK(j.is_discarded());
|
||||
CHECK(!j.is_primitive());
|
||||
CHECK(!j.is_structured());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("serialization")
|
||||
{
|
||||
json j {{"object", json::object()}, {"array", {1, 2, 3, 4}}, {"number", 42}, {"boolean", false}, {"null", nullptr}, {"string", "Hello world"} };
|
||||
|
||||
SECTION("no indent / indent=-1")
|
||||
{
|
||||
CHECK(j.dump() ==
|
||||
"{\"array\":[1,2,3,4],\"boolean\":false,\"null\":null,\"number\":42,\"object\":{},\"string\":\"Hello world\"}");
|
||||
|
||||
CHECK(j.dump() == j.dump(-1));
|
||||
}
|
||||
|
||||
SECTION("indent=0")
|
||||
{
|
||||
CHECK(j.dump(0) ==
|
||||
"{\n\"array\": [\n1,\n2,\n3,\n4\n],\n\"boolean\": false,\n\"null\": null,\n\"number\": 42,\n\"object\": {},\n\"string\": \"Hello world\"\n}");
|
||||
}
|
||||
|
||||
SECTION("indent=1, space='\t'")
|
||||
{
|
||||
CHECK(j.dump(1, '\t') ==
|
||||
"{\n\t\"array\": [\n\t\t1,\n\t\t2,\n\t\t3,\n\t\t4\n\t],\n\t\"boolean\": false,\n\t\"null\": null,\n\t\"number\": 42,\n\t\"object\": {},\n\t\"string\": \"Hello world\"\n}");
|
||||
}
|
||||
|
||||
SECTION("indent=4")
|
||||
{
|
||||
CHECK(j.dump(4) ==
|
||||
"{\n \"array\": [\n 1,\n 2,\n 3,\n 4\n ],\n \"boolean\": false,\n \"null\": null,\n \"number\": 42,\n \"object\": {},\n \"string\": \"Hello world\"\n}");
|
||||
}
|
||||
|
||||
SECTION("indent=x")
|
||||
{
|
||||
CHECK(j.dump().size() == 94);
|
||||
CHECK(j.dump(1).size() == 127);
|
||||
CHECK(j.dump(2).size() == 142);
|
||||
CHECK(j.dump(512).size() == 7792);
|
||||
|
||||
// important test, because it yields a resize of the indent_string
|
||||
// inside the dump() function
|
||||
CHECK(j.dump(1024).size() == 15472);
|
||||
|
||||
const auto binary = json::binary({1, 2, 3}, 128);
|
||||
CHECK(binary.dump(1024).size() == 2086);
|
||||
}
|
||||
|
||||
SECTION("dump and floating-point numbers")
|
||||
{
|
||||
auto s = json(42.23).dump();
|
||||
CHECK(s.find("42.23") != std::string::npos);
|
||||
}
|
||||
|
||||
SECTION("dump and small floating-point numbers")
|
||||
{
|
||||
auto s = json(1.23456e-78).dump();
|
||||
CHECK(s.find("1.23456e-78") != std::string::npos);
|
||||
}
|
||||
|
||||
SECTION("dump and non-ASCII characters")
|
||||
{
|
||||
CHECK(json("ä").dump() == "\"ä\"");
|
||||
CHECK(json("Ö").dump() == "\"Ö\"");
|
||||
CHECK(json("❤️").dump() == "\"❤️\"");
|
||||
}
|
||||
|
||||
SECTION("dump with ensure_ascii and non-ASCII characters")
|
||||
{
|
||||
CHECK(json("ä").dump(-1, ' ', true) == "\"\\u00e4\"");
|
||||
CHECK(json("Ö").dump(-1, ' ', true) == "\"\\u00d6\"");
|
||||
CHECK(json("❤️").dump(-1, ' ', true) == "\"\\u2764\\ufe0f\"");
|
||||
}
|
||||
|
||||
SECTION("full Unicode escaping to ASCII")
|
||||
{
|
||||
SECTION("parsing yields the same JSON value")
|
||||
{
|
||||
std::ifstream f_escaped(TEST_DATA_DIRECTORY "/json_nlohmann_tests/all_unicode_ascii.json");
|
||||
std::ifstream f_unescaped(TEST_DATA_DIRECTORY "/json_nlohmann_tests/all_unicode.json");
|
||||
|
||||
json j1 = json::parse(f_escaped);
|
||||
json j2 = json::parse(f_unescaped);
|
||||
CHECK(j1 == j2);
|
||||
}
|
||||
|
||||
SECTION("dumping yields the same JSON text")
|
||||
{
|
||||
std::ifstream f_escaped(TEST_DATA_DIRECTORY "/json_nlohmann_tests/all_unicode_ascii.json");
|
||||
std::ifstream f_unescaped(TEST_DATA_DIRECTORY "/json_nlohmann_tests/all_unicode.json");
|
||||
|
||||
json value = json::parse(f_unescaped);
|
||||
std::string text = value.dump(4, ' ', true);
|
||||
|
||||
std::string expected((std::istreambuf_iterator<char>(f_escaped)),
|
||||
std::istreambuf_iterator<char>());
|
||||
CHECK(text == expected);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("serialization of discarded element")
|
||||
{
|
||||
json j_discarded(json::value_t::discarded);
|
||||
CHECK(j_discarded.dump() == "<discarded>");
|
||||
}
|
||||
|
||||
SECTION("check that precision is reset after serialization")
|
||||
{
|
||||
// create stringstream and set precision
|
||||
std::stringstream ss;
|
||||
ss.precision(3);
|
||||
ss << 3.141592653589793 << std::fixed;
|
||||
CHECK(ss.str() == "3.14");
|
||||
|
||||
// reset stringstream
|
||||
ss.str(std::string());
|
||||
|
||||
// use stringstream for JSON serialization
|
||||
json j_number = 3.14159265358979;
|
||||
ss << j_number;
|
||||
|
||||
// check that precision has been overridden during serialization
|
||||
CHECK(ss.str() == "3.14159265358979");
|
||||
|
||||
// check that precision has been restored
|
||||
CHECK(ss.precision() == 3);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("round trips")
|
||||
{
|
||||
for (const auto& s :
|
||||
{"3.141592653589793", "1000000000000000010E5"
|
||||
})
|
||||
{
|
||||
json j1 = json::parse(s);
|
||||
std::string s1 = j1.dump();
|
||||
json j2 = json::parse(s1);
|
||||
std::string s2 = j2.dump();
|
||||
CHECK(s1 == s2);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("return the type of the object (explicit)")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j = nullptr;
|
||||
CHECK(j.type() == json::value_t::null);
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j = {{"foo", "bar"}};
|
||||
CHECK(j.type() == json::value_t::object);
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j = {1, 2, 3, 4};
|
||||
CHECK(j.type() == json::value_t::array);
|
||||
}
|
||||
|
||||
SECTION("boolean")
|
||||
{
|
||||
json j = true;
|
||||
CHECK(j.type() == json::value_t::boolean);
|
||||
}
|
||||
|
||||
SECTION("string")
|
||||
{
|
||||
json j = "Hello world";
|
||||
CHECK(j.type() == json::value_t::string);
|
||||
}
|
||||
|
||||
SECTION("number (integer)")
|
||||
{
|
||||
json j = 23;
|
||||
CHECK(j.type() == json::value_t::number_integer);
|
||||
}
|
||||
|
||||
SECTION("number (unsigned)")
|
||||
{
|
||||
json j = 23u;
|
||||
CHECK(j.type() == json::value_t::number_unsigned);
|
||||
}
|
||||
|
||||
SECTION("number (floating-point)")
|
||||
{
|
||||
json j = 42.23;
|
||||
CHECK(j.type() == json::value_t::number_float);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("return the type of the object (implicit)")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j = nullptr;
|
||||
json::value_t t = j;
|
||||
CHECK(t == j.type());
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j = {{"foo", "bar"}};
|
||||
json::value_t t = j;
|
||||
CHECK(t == j.type());
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j = {1, 2, 3, 4};
|
||||
json::value_t t = j;
|
||||
CHECK(t == j.type());
|
||||
}
|
||||
|
||||
SECTION("boolean")
|
||||
{
|
||||
json j = true;
|
||||
json::value_t t = j;
|
||||
CHECK(t == j.type());
|
||||
}
|
||||
|
||||
SECTION("string")
|
||||
{
|
||||
json j = "Hello world";
|
||||
json::value_t t = j;
|
||||
CHECK(t == j.type());
|
||||
}
|
||||
|
||||
SECTION("number (integer)")
|
||||
{
|
||||
json j = 23;
|
||||
json::value_t t = j;
|
||||
CHECK(t == j.type());
|
||||
}
|
||||
|
||||
SECTION("number (unsigned)")
|
||||
{
|
||||
json j = 23u;
|
||||
json::value_t t = j;
|
||||
CHECK(t == j.type());
|
||||
}
|
||||
|
||||
SECTION("number (floating-point)")
|
||||
{
|
||||
json j = 42.23;
|
||||
json::value_t t = j;
|
||||
CHECK(t == j.type());
|
||||
}
|
||||
|
||||
SECTION("binary")
|
||||
{
|
||||
json j = json::binary({});
|
||||
json::value_t t = j;
|
||||
CHECK(t == j.type());
|
||||
}
|
||||
}
|
||||
}
|
||||
1458
vendor/json/test/src/unit-items.cpp
vendored
Normal file
1691
vendor/json/test/src/unit-iterators1.cpp
vendored
Normal file
1000
vendor/json/test/src/unit-iterators2.cpp
vendored
Normal file
1378
vendor/json/test/src/unit-json_patch.cpp
vendored
Normal file
697
vendor/json/test/src/unit-json_pointer.cpp
vendored
Normal file
@@ -0,0 +1,697 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#define JSON_TESTS_PRIVATE
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
TEST_CASE("JSON pointers")
|
||||
{
|
||||
SECTION("errors")
|
||||
{
|
||||
CHECK_THROWS_AS(json::json_pointer("foo"), json::parse_error&);
|
||||
CHECK_THROWS_WITH(json::json_pointer("foo"),
|
||||
"[json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo'");
|
||||
|
||||
CHECK_THROWS_AS(json::json_pointer("/~~"), json::parse_error&);
|
||||
CHECK_THROWS_WITH(json::json_pointer("/~~"),
|
||||
"[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'");
|
||||
|
||||
CHECK_THROWS_AS(json::json_pointer("/~"), json::parse_error&);
|
||||
CHECK_THROWS_WITH(json::json_pointer("/~"),
|
||||
"[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'");
|
||||
|
||||
json::json_pointer p;
|
||||
CHECK_THROWS_AS(p.top(), json::out_of_range&);
|
||||
CHECK_THROWS_WITH(p.top(),
|
||||
"[json.exception.out_of_range.405] JSON pointer has no parent");
|
||||
CHECK_THROWS_AS(p.pop_back(), json::out_of_range&);
|
||||
CHECK_THROWS_WITH(p.pop_back(),
|
||||
"[json.exception.out_of_range.405] JSON pointer has no parent");
|
||||
|
||||
SECTION("array index error")
|
||||
{
|
||||
json v = {1, 2, 3, 4};
|
||||
json::json_pointer ptr("/10e");
|
||||
CHECK_THROWS_AS(v[ptr], json::out_of_range&);
|
||||
CHECK_THROWS_WITH(v[ptr],
|
||||
"[json.exception.out_of_range.404] unresolved reference token '10e'");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("examples from RFC 6901")
|
||||
{
|
||||
SECTION("nonconst access")
|
||||
{
|
||||
json j = R"(
|
||||
{
|
||||
"foo": ["bar", "baz"],
|
||||
"": 0,
|
||||
"a/b": 1,
|
||||
"c%d": 2,
|
||||
"e^f": 3,
|
||||
"g|h": 4,
|
||||
"i\\j": 5,
|
||||
"k\"l": 6,
|
||||
" ": 7,
|
||||
"m~n": 8
|
||||
}
|
||||
)"_json;
|
||||
|
||||
// the whole document
|
||||
CHECK(j[json::json_pointer()] == j);
|
||||
CHECK(j[json::json_pointer("")] == j);
|
||||
CHECK(j.contains(json::json_pointer()));
|
||||
CHECK(j.contains(json::json_pointer("")));
|
||||
|
||||
// array access
|
||||
CHECK(j[json::json_pointer("/foo")] == j["foo"]);
|
||||
CHECK(j.contains(json::json_pointer("/foo")));
|
||||
CHECK(j[json::json_pointer("/foo/0")] == j["foo"][0]);
|
||||
CHECK(j[json::json_pointer("/foo/1")] == j["foo"][1]);
|
||||
CHECK(j["/foo/1"_json_pointer] == j["foo"][1]);
|
||||
CHECK(j.contains(json::json_pointer("/foo/0")));
|
||||
CHECK(j.contains(json::json_pointer("/foo/1")));
|
||||
CHECK(!j.contains(json::json_pointer("/foo/3")));
|
||||
CHECK(!j.contains(json::json_pointer("/foo/+")));
|
||||
CHECK(!j.contains(json::json_pointer("/foo/1+2")));
|
||||
CHECK(!j.contains(json::json_pointer("/foo/-")));
|
||||
|
||||
// checked array access
|
||||
CHECK(j.at(json::json_pointer("/foo/0")) == j["foo"][0]);
|
||||
CHECK(j.at(json::json_pointer("/foo/1")) == j["foo"][1]);
|
||||
|
||||
// empty string access
|
||||
CHECK(j[json::json_pointer("/")] == j[""]);
|
||||
CHECK(j.contains(json::json_pointer("")));
|
||||
CHECK(j.contains(json::json_pointer("/")));
|
||||
|
||||
// other cases
|
||||
CHECK(j[json::json_pointer("/ ")] == j[" "]);
|
||||
CHECK(j[json::json_pointer("/c%d")] == j["c%d"]);
|
||||
CHECK(j[json::json_pointer("/e^f")] == j["e^f"]);
|
||||
CHECK(j[json::json_pointer("/g|h")] == j["g|h"]);
|
||||
CHECK(j[json::json_pointer("/i\\j")] == j["i\\j"]);
|
||||
CHECK(j[json::json_pointer("/k\"l")] == j["k\"l"]);
|
||||
|
||||
// contains
|
||||
CHECK(j.contains(json::json_pointer("/ ")));
|
||||
CHECK(j.contains(json::json_pointer("/c%d")));
|
||||
CHECK(j.contains(json::json_pointer("/e^f")));
|
||||
CHECK(j.contains(json::json_pointer("/g|h")));
|
||||
CHECK(j.contains(json::json_pointer("/i\\j")));
|
||||
CHECK(j.contains(json::json_pointer("/k\"l")));
|
||||
|
||||
// checked access
|
||||
CHECK(j.at(json::json_pointer("/ ")) == j[" "]);
|
||||
CHECK(j.at(json::json_pointer("/c%d")) == j["c%d"]);
|
||||
CHECK(j.at(json::json_pointer("/e^f")) == j["e^f"]);
|
||||
CHECK(j.at(json::json_pointer("/g|h")) == j["g|h"]);
|
||||
CHECK(j.at(json::json_pointer("/i\\j")) == j["i\\j"]);
|
||||
CHECK(j.at(json::json_pointer("/k\"l")) == j["k\"l"]);
|
||||
|
||||
// escaped access
|
||||
CHECK(j[json::json_pointer("/a~1b")] == j["a/b"]);
|
||||
CHECK(j[json::json_pointer("/m~0n")] == j["m~n"]);
|
||||
CHECK(j.contains(json::json_pointer("/a~1b")));
|
||||
CHECK(j.contains(json::json_pointer("/m~0n")));
|
||||
|
||||
// unescaped access
|
||||
// access to nonexisting values yield object creation
|
||||
CHECK(!j.contains(json::json_pointer("/a/b")));
|
||||
CHECK_NOTHROW(j[json::json_pointer("/a/b")] = 42);
|
||||
CHECK(j.contains(json::json_pointer("/a/b")));
|
||||
CHECK(j["a"]["b"] == json(42));
|
||||
|
||||
CHECK(!j.contains(json::json_pointer("/a/c/1")));
|
||||
CHECK_NOTHROW(j[json::json_pointer("/a/c/1")] = 42);
|
||||
CHECK(j["a"]["c"] == json({nullptr, 42}));
|
||||
CHECK(j.contains(json::json_pointer("/a/c/1")));
|
||||
|
||||
CHECK(!j.contains(json::json_pointer("/a/d/-")));
|
||||
CHECK_NOTHROW(j[json::json_pointer("/a/d/-")] = 42);
|
||||
CHECK(!j.contains(json::json_pointer("/a/d/-")));
|
||||
CHECK(j["a"]["d"] == json::array({42}));
|
||||
// "/a/b" works for JSON {"a": {"b": 42}}
|
||||
CHECK(json({{"a", {{"b", 42}}}})[json::json_pointer("/a/b")] == json(42));
|
||||
|
||||
// unresolved access
|
||||
json j_primitive = 1;
|
||||
CHECK_THROWS_AS(j_primitive["/foo"_json_pointer], json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j_primitive["/foo"_json_pointer],
|
||||
"[json.exception.out_of_range.404] unresolved reference token 'foo'");
|
||||
CHECK_THROWS_AS(j_primitive.at("/foo"_json_pointer), json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j_primitive.at("/foo"_json_pointer),
|
||||
"[json.exception.out_of_range.404] unresolved reference token 'foo'");
|
||||
CHECK(!j_primitive.contains(json::json_pointer("/foo")));
|
||||
}
|
||||
|
||||
SECTION("const access")
|
||||
{
|
||||
const json j = R"(
|
||||
{
|
||||
"foo": ["bar", "baz"],
|
||||
"": 0,
|
||||
"a/b": 1,
|
||||
"c%d": 2,
|
||||
"e^f": 3,
|
||||
"g|h": 4,
|
||||
"i\\j": 5,
|
||||
"k\"l": 6,
|
||||
" ": 7,
|
||||
"m~n": 8
|
||||
}
|
||||
)"_json;
|
||||
|
||||
// the whole document
|
||||
CHECK(j[json::json_pointer()] == j);
|
||||
CHECK(j[json::json_pointer("")] == j);
|
||||
|
||||
// array access
|
||||
CHECK(j[json::json_pointer("/foo")] == j["foo"]);
|
||||
CHECK(j[json::json_pointer("/foo/0")] == j["foo"][0]);
|
||||
CHECK(j[json::json_pointer("/foo/1")] == j["foo"][1]);
|
||||
CHECK(j["/foo/1"_json_pointer] == j["foo"][1]);
|
||||
|
||||
// checked array access
|
||||
CHECK(j.at(json::json_pointer("/foo/0")) == j["foo"][0]);
|
||||
CHECK(j.at(json::json_pointer("/foo/1")) == j["foo"][1]);
|
||||
|
||||
// empty string access
|
||||
CHECK(j[json::json_pointer("/")] == j[""]);
|
||||
|
||||
// other cases
|
||||
CHECK(j[json::json_pointer("/ ")] == j[" "]);
|
||||
CHECK(j[json::json_pointer("/c%d")] == j["c%d"]);
|
||||
CHECK(j[json::json_pointer("/e^f")] == j["e^f"]);
|
||||
CHECK(j[json::json_pointer("/g|h")] == j["g|h"]);
|
||||
CHECK(j[json::json_pointer("/i\\j")] == j["i\\j"]);
|
||||
CHECK(j[json::json_pointer("/k\"l")] == j["k\"l"]);
|
||||
|
||||
// checked access
|
||||
CHECK(j.at(json::json_pointer("/ ")) == j[" "]);
|
||||
CHECK(j.at(json::json_pointer("/c%d")) == j["c%d"]);
|
||||
CHECK(j.at(json::json_pointer("/e^f")) == j["e^f"]);
|
||||
CHECK(j.at(json::json_pointer("/g|h")) == j["g|h"]);
|
||||
CHECK(j.at(json::json_pointer("/i\\j")) == j["i\\j"]);
|
||||
CHECK(j.at(json::json_pointer("/k\"l")) == j["k\"l"]);
|
||||
|
||||
// escaped access
|
||||
CHECK(j[json::json_pointer("/a~1b")] == j["a/b"]);
|
||||
CHECK(j[json::json_pointer("/m~0n")] == j["m~n"]);
|
||||
|
||||
// unescaped access
|
||||
CHECK_THROWS_AS(j.at(json::json_pointer("/a/b")), json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j.at(json::json_pointer("/a/b")),
|
||||
"[json.exception.out_of_range.403] key 'a' not found");
|
||||
|
||||
// unresolved access
|
||||
const json j_primitive = 1;
|
||||
CHECK_THROWS_AS(j_primitive["/foo"_json_pointer], json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j_primitive["/foo"_json_pointer],
|
||||
"[json.exception.out_of_range.404] unresolved reference token 'foo'");
|
||||
CHECK_THROWS_AS(j_primitive.at("/foo"_json_pointer), json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j_primitive.at("/foo"_json_pointer),
|
||||
"[json.exception.out_of_range.404] unresolved reference token 'foo'");
|
||||
}
|
||||
|
||||
SECTION("user-defined string literal")
|
||||
{
|
||||
json j = R"(
|
||||
{
|
||||
"foo": ["bar", "baz"],
|
||||
"": 0,
|
||||
"a/b": 1,
|
||||
"c%d": 2,
|
||||
"e^f": 3,
|
||||
"g|h": 4,
|
||||
"i\\j": 5,
|
||||
"k\"l": 6,
|
||||
" ": 7,
|
||||
"m~n": 8
|
||||
}
|
||||
)"_json;
|
||||
|
||||
// the whole document
|
||||
CHECK(j[""_json_pointer] == j);
|
||||
CHECK(j.contains(""_json_pointer));
|
||||
|
||||
// array access
|
||||
CHECK(j["/foo"_json_pointer] == j["foo"]);
|
||||
CHECK(j["/foo/0"_json_pointer] == j["foo"][0]);
|
||||
CHECK(j["/foo/1"_json_pointer] == j["foo"][1]);
|
||||
CHECK(j.contains("/foo"_json_pointer));
|
||||
CHECK(j.contains("/foo/0"_json_pointer));
|
||||
CHECK(j.contains("/foo/1"_json_pointer));
|
||||
CHECK(!j.contains("/foo/-"_json_pointer));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("array access")
|
||||
{
|
||||
SECTION("nonconst access")
|
||||
{
|
||||
json j = {1, 2, 3};
|
||||
const json j_const = j;
|
||||
|
||||
// check reading access
|
||||
CHECK(j["/0"_json_pointer] == j[0]);
|
||||
CHECK(j["/1"_json_pointer] == j[1]);
|
||||
CHECK(j["/2"_json_pointer] == j[2]);
|
||||
|
||||
// assign to existing index
|
||||
j["/1"_json_pointer] = 13;
|
||||
CHECK(j[1] == json(13));
|
||||
|
||||
// assign to nonexisting index
|
||||
j["/3"_json_pointer] = 33;
|
||||
CHECK(j[3] == json(33));
|
||||
|
||||
// assign to nonexisting index (with gap)
|
||||
j["/5"_json_pointer] = 55;
|
||||
CHECK(j == json({1, 13, 3, 33, nullptr, 55}));
|
||||
|
||||
// error with leading 0
|
||||
CHECK_THROWS_AS(j["/01"_json_pointer], json::parse_error&);
|
||||
CHECK_THROWS_WITH(j["/01"_json_pointer],
|
||||
"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'");
|
||||
CHECK_THROWS_AS(j_const["/01"_json_pointer], json::parse_error&);
|
||||
CHECK_THROWS_WITH(j_const["/01"_json_pointer],
|
||||
"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'");
|
||||
CHECK_THROWS_AS(j.at("/01"_json_pointer), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.at("/01"_json_pointer),
|
||||
"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'");
|
||||
CHECK_THROWS_AS(j_const.at("/01"_json_pointer), json::parse_error&);
|
||||
CHECK_THROWS_WITH(j_const.at("/01"_json_pointer),
|
||||
"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'");
|
||||
|
||||
CHECK(!j.contains("/01"_json_pointer));
|
||||
CHECK(!j.contains("/01"_json_pointer));
|
||||
CHECK(!j_const.contains("/01"_json_pointer));
|
||||
CHECK(!j_const.contains("/01"_json_pointer));
|
||||
|
||||
// error with incorrect numbers
|
||||
CHECK_THROWS_AS(j["/one"_json_pointer] = 1, json::parse_error&);
|
||||
CHECK_THROWS_WITH(j["/one"_json_pointer] = 1,
|
||||
"[json.exception.parse_error.109] parse error: array index 'one' is not a number");
|
||||
CHECK_THROWS_AS(j_const["/one"_json_pointer] == 1, json::parse_error&);
|
||||
CHECK_THROWS_WITH(j_const["/one"_json_pointer] == 1,
|
||||
"[json.exception.parse_error.109] parse error: array index 'one' is not a number");
|
||||
|
||||
CHECK_THROWS_AS(j.at("/one"_json_pointer) = 1, json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.at("/one"_json_pointer) = 1,
|
||||
"[json.exception.parse_error.109] parse error: array index 'one' is not a number");
|
||||
CHECK_THROWS_AS(j_const.at("/one"_json_pointer) == 1, json::parse_error&);
|
||||
CHECK_THROWS_WITH(j_const.at("/one"_json_pointer) == 1,
|
||||
"[json.exception.parse_error.109] parse error: array index 'one' is not a number");
|
||||
|
||||
CHECK_THROWS_AS(j["/+1"_json_pointer] = 1, json::parse_error&);
|
||||
CHECK_THROWS_WITH(j["/+1"_json_pointer] = 1,
|
||||
"[json.exception.parse_error.109] parse error: array index '+1' is not a number");
|
||||
CHECK_THROWS_AS(j_const["/+1"_json_pointer] == 1, json::parse_error&);
|
||||
CHECK_THROWS_WITH(j_const["/+1"_json_pointer] == 1,
|
||||
"[json.exception.parse_error.109] parse error: array index '+1' is not a number");
|
||||
|
||||
CHECK_THROWS_AS(j["/1+1"_json_pointer] = 1, json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j["/1+1"_json_pointer] = 1,
|
||||
"[json.exception.out_of_range.404] unresolved reference token '1+1'");
|
||||
CHECK_THROWS_AS(j_const["/1+1"_json_pointer] == 1, json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j_const["/1+1"_json_pointer] == 1,
|
||||
"[json.exception.out_of_range.404] unresolved reference token '1+1'");
|
||||
|
||||
{
|
||||
auto too_large_index = std::to_string((std::numeric_limits<unsigned long long>::max)()) + "1";
|
||||
json::json_pointer jp(std::string("/") + too_large_index);
|
||||
std::string throw_msg = std::string("[json.exception.out_of_range.404] unresolved reference token '") + too_large_index + "'";
|
||||
|
||||
CHECK_THROWS_AS(j[jp] = 1, json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j[jp] = 1, throw_msg.c_str());
|
||||
CHECK_THROWS_AS(j_const[jp] == 1, json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j_const[jp] == 1, throw_msg.c_str());
|
||||
}
|
||||
|
||||
if (sizeof(typename json::size_type) < sizeof(unsigned long long))
|
||||
{
|
||||
auto size_type_max_uul = static_cast<unsigned long long>((std::numeric_limits<json::size_type>::max)());
|
||||
auto too_large_index = std::to_string(size_type_max_uul);
|
||||
json::json_pointer jp(std::string("/") + too_large_index);
|
||||
std::string throw_msg = std::string("[json.exception.out_of_range.410] array index ") + too_large_index + " exceeds size_type";
|
||||
|
||||
CHECK_THROWS_AS(j[jp] = 1, json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j[jp] = 1, throw_msg.c_str());
|
||||
CHECK_THROWS_AS(j_const[jp] == 1, json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j_const[jp] == 1, throw_msg.c_str());
|
||||
}
|
||||
|
||||
CHECK_THROWS_AS(j.at("/one"_json_pointer) = 1, json::parse_error&);
|
||||
CHECK_THROWS_WITH(j.at("/one"_json_pointer) = 1,
|
||||
"[json.exception.parse_error.109] parse error: array index 'one' is not a number");
|
||||
CHECK_THROWS_AS(j_const.at("/one"_json_pointer) == 1, json::parse_error&);
|
||||
CHECK_THROWS_WITH(j_const.at("/one"_json_pointer) == 1,
|
||||
"[json.exception.parse_error.109] parse error: array index 'one' is not a number");
|
||||
|
||||
CHECK(!j.contains("/one"_json_pointer));
|
||||
CHECK(!j.contains("/one"_json_pointer));
|
||||
CHECK(!j_const.contains("/one"_json_pointer));
|
||||
CHECK(!j_const.contains("/one"_json_pointer));
|
||||
|
||||
CHECK_THROWS_AS(json({{"/list/0", 1}, {"/list/1", 2}, {"/list/three", 3}}).unflatten(), json::parse_error&);
|
||||
CHECK_THROWS_WITH(json({{"/list/0", 1}, {"/list/1", 2}, {"/list/three", 3}}).unflatten(),
|
||||
"[json.exception.parse_error.109] parse error: array index 'three' is not a number");
|
||||
|
||||
// assign to "-"
|
||||
j["/-"_json_pointer] = 99;
|
||||
CHECK(j == json({1, 13, 3, 33, nullptr, 55, 99}));
|
||||
|
||||
// error when using "-" in const object
|
||||
CHECK_THROWS_AS(j_const["/-"_json_pointer], json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j_const["/-"_json_pointer],
|
||||
"[json.exception.out_of_range.402] array index '-' (3) is out of range");
|
||||
CHECK(!j_const.contains("/-"_json_pointer));
|
||||
|
||||
// error when using "-" with at
|
||||
CHECK_THROWS_AS(j.at("/-"_json_pointer), json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j.at("/-"_json_pointer),
|
||||
"[json.exception.out_of_range.402] array index '-' (7) is out of range");
|
||||
CHECK_THROWS_AS(j_const.at("/-"_json_pointer), json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j_const.at("/-"_json_pointer),
|
||||
"[json.exception.out_of_range.402] array index '-' (3) is out of range");
|
||||
CHECK(!j_const.contains("/-"_json_pointer));
|
||||
}
|
||||
|
||||
SECTION("const access")
|
||||
{
|
||||
const json j = {1, 2, 3};
|
||||
|
||||
// check reading access
|
||||
CHECK(j["/0"_json_pointer] == j[0]);
|
||||
CHECK(j["/1"_json_pointer] == j[1]);
|
||||
CHECK(j["/2"_json_pointer] == j[2]);
|
||||
|
||||
// assign to nonexisting index
|
||||
CHECK_THROWS_AS(j.at("/3"_json_pointer), json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j.at("/3"_json_pointer),
|
||||
"[json.exception.out_of_range.401] array index 3 is out of range");
|
||||
CHECK(!j.contains("/3"_json_pointer));
|
||||
|
||||
// assign to nonexisting index (with gap)
|
||||
CHECK_THROWS_AS(j.at("/5"_json_pointer), json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j.at("/5"_json_pointer),
|
||||
"[json.exception.out_of_range.401] array index 5 is out of range");
|
||||
CHECK(!j.contains("/5"_json_pointer));
|
||||
|
||||
// assign to "-"
|
||||
CHECK_THROWS_AS(j["/-"_json_pointer], json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j["/-"_json_pointer],
|
||||
"[json.exception.out_of_range.402] array index '-' (3) is out of range");
|
||||
CHECK_THROWS_AS(j.at("/-"_json_pointer), json::out_of_range&);
|
||||
CHECK_THROWS_WITH(j.at("/-"_json_pointer),
|
||||
"[json.exception.out_of_range.402] array index '-' (3) is out of range");
|
||||
CHECK(!j.contains("/-"_json_pointer));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("flatten")
|
||||
{
|
||||
json j =
|
||||
{
|
||||
{"pi", 3.141},
|
||||
{"happy", true},
|
||||
{"name", "Niels"},
|
||||
{"nothing", nullptr},
|
||||
{
|
||||
"answer", {
|
||||
{"everything", 42}
|
||||
}
|
||||
},
|
||||
{"list", {1, 0, 2}},
|
||||
{
|
||||
"object", {
|
||||
{"currency", "USD"},
|
||||
{"value", 42.99},
|
||||
{"", "empty string"},
|
||||
{"/", "slash"},
|
||||
{"~", "tilde"},
|
||||
{"~1", "tilde1"}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
json j_flatten =
|
||||
{
|
||||
{"/pi", 3.141},
|
||||
{"/happy", true},
|
||||
{"/name", "Niels"},
|
||||
{"/nothing", nullptr},
|
||||
{"/answer/everything", 42},
|
||||
{"/list/0", 1},
|
||||
{"/list/1", 0},
|
||||
{"/list/2", 2},
|
||||
{"/object/currency", "USD"},
|
||||
{"/object/value", 42.99},
|
||||
{"/object/", "empty string"},
|
||||
{"/object/~1", "slash"},
|
||||
{"/object/~0", "tilde"},
|
||||
{"/object/~01", "tilde1"}
|
||||
};
|
||||
|
||||
// check if flattened result is as expected
|
||||
CHECK(j.flatten() == j_flatten);
|
||||
|
||||
// check if unflattened result is as expected
|
||||
CHECK(j_flatten.unflatten() == j);
|
||||
|
||||
// error for nonobjects
|
||||
CHECK_THROWS_AS(json(1).unflatten(), json::type_error&);
|
||||
CHECK_THROWS_WITH(json(1).unflatten(),
|
||||
"[json.exception.type_error.314] only objects can be unflattened");
|
||||
|
||||
// error for nonprimitve values
|
||||
CHECK_THROWS_AS(json({{"/1", {1, 2, 3}}}).unflatten(), json::type_error&);
|
||||
#if JSON_DIAGNOSTICS
|
||||
CHECK_THROWS_WITH(json({{"/1", {1, 2, 3}}}).unflatten(), "[json.exception.type_error.315] (/~11) values in object must be primitive");
|
||||
#else
|
||||
CHECK_THROWS_WITH(json({{"/1", {1, 2, 3}}}).unflatten(), "[json.exception.type_error.315] values in object must be primitive");
|
||||
#endif
|
||||
|
||||
// error for conflicting values
|
||||
json j_error = {{"", 42}, {"/foo", 17}};
|
||||
CHECK_THROWS_AS(j_error.unflatten(), json::type_error&);
|
||||
CHECK_THROWS_WITH(j_error.unflatten(),
|
||||
"[json.exception.type_error.313] invalid value to unflatten");
|
||||
|
||||
// explicit roundtrip check
|
||||
CHECK(j.flatten().unflatten() == j);
|
||||
|
||||
// roundtrip for primitive values
|
||||
json j_null;
|
||||
CHECK(j_null.flatten().unflatten() == j_null);
|
||||
json j_number = 42;
|
||||
CHECK(j_number.flatten().unflatten() == j_number);
|
||||
json j_boolean = false;
|
||||
CHECK(j_boolean.flatten().unflatten() == j_boolean);
|
||||
json j_string = "foo";
|
||||
CHECK(j_string.flatten().unflatten() == j_string);
|
||||
|
||||
// roundtrip for empty structured values (will be unflattened to null)
|
||||
json j_array(json::value_t::array);
|
||||
CHECK(j_array.flatten().unflatten() == json());
|
||||
json j_object(json::value_t::object);
|
||||
CHECK(j_object.flatten().unflatten() == json());
|
||||
}
|
||||
|
||||
SECTION("string representation")
|
||||
{
|
||||
for (auto ptr :
|
||||
{"", "/foo", "/foo/0", "/", "/a~1b", "/c%d", "/e^f", "/g|h", "/i\\j", "/k\"l", "/ ", "/m~0n"
|
||||
})
|
||||
{
|
||||
CHECK(json::json_pointer(ptr).to_string() == ptr);
|
||||
CHECK(std::string(json::json_pointer(ptr)) == ptr);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("conversion")
|
||||
{
|
||||
SECTION("array")
|
||||
{
|
||||
json j;
|
||||
// all numbers -> array
|
||||
j["/12"_json_pointer] = 0;
|
||||
CHECK(j.is_array());
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j;
|
||||
// contains a number, but is not a number -> object
|
||||
j["/a12"_json_pointer] = 0;
|
||||
CHECK(j.is_object());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("empty, push, pop and parent")
|
||||
{
|
||||
const json j =
|
||||
{
|
||||
{"", "Hello"},
|
||||
{"pi", 3.141},
|
||||
{"happy", true},
|
||||
{"name", "Niels"},
|
||||
{"nothing", nullptr},
|
||||
{
|
||||
"answer", {
|
||||
{"everything", 42}
|
||||
}
|
||||
},
|
||||
{"list", {1, 0, 2}},
|
||||
{
|
||||
"object", {
|
||||
{"currency", "USD"},
|
||||
{"value", 42.99},
|
||||
{"", "empty string"},
|
||||
{"/", "slash"},
|
||||
{"~", "tilde"},
|
||||
{"~1", "tilde1"}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// empty json_pointer returns the root JSON-object
|
||||
auto ptr = ""_json_pointer;
|
||||
CHECK(ptr.empty());
|
||||
CHECK(j[ptr] == j);
|
||||
|
||||
// simple field access
|
||||
ptr.push_back("pi");
|
||||
CHECK(!ptr.empty());
|
||||
CHECK(j[ptr] == j["pi"]);
|
||||
|
||||
ptr.pop_back();
|
||||
CHECK(ptr.empty());
|
||||
CHECK(j[ptr] == j);
|
||||
|
||||
// object and children access
|
||||
const std::string answer("answer");
|
||||
ptr.push_back(answer);
|
||||
ptr.push_back("everything");
|
||||
CHECK(!ptr.empty());
|
||||
CHECK(j[ptr] == j["answer"]["everything"]);
|
||||
|
||||
// check access via const pointer
|
||||
const auto cptr = ptr;
|
||||
CHECK(cptr.back() == "everything");
|
||||
|
||||
ptr.pop_back();
|
||||
ptr.pop_back();
|
||||
CHECK(ptr.empty());
|
||||
CHECK(j[ptr] == j);
|
||||
|
||||
// push key which has to be encoded
|
||||
ptr.push_back("object");
|
||||
ptr.push_back("/");
|
||||
CHECK(j[ptr] == j["object"]["/"]);
|
||||
CHECK(ptr.to_string() == "/object/~1");
|
||||
|
||||
CHECK(j[ptr.parent_pointer()] == j["object"]);
|
||||
ptr = ptr.parent_pointer().parent_pointer();
|
||||
CHECK(ptr.empty());
|
||||
CHECK(j[ptr] == j);
|
||||
// parent-pointer of the empty json_pointer is empty
|
||||
ptr = ptr.parent_pointer();
|
||||
CHECK(ptr.empty());
|
||||
CHECK(j[ptr] == j);
|
||||
|
||||
CHECK_THROWS_WITH(ptr.pop_back(),
|
||||
"[json.exception.out_of_range.405] JSON pointer has no parent");
|
||||
}
|
||||
|
||||
SECTION("operators")
|
||||
{
|
||||
const json j =
|
||||
{
|
||||
{"", "Hello"},
|
||||
{"pi", 3.141},
|
||||
{"happy", true},
|
||||
{"name", "Niels"},
|
||||
{"nothing", nullptr},
|
||||
{
|
||||
"answer", {
|
||||
{"everything", 42}
|
||||
}
|
||||
},
|
||||
{"list", {1, 0, 2}},
|
||||
{
|
||||
"object", {
|
||||
{"currency", "USD"},
|
||||
{"value", 42.99},
|
||||
{"", "empty string"},
|
||||
{"/", "slash"},
|
||||
{"~", "tilde"},
|
||||
{"~1", "tilde1"}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// empty json_pointer returns the root JSON-object
|
||||
auto ptr = ""_json_pointer;
|
||||
CHECK(j[ptr] == j);
|
||||
|
||||
// simple field access
|
||||
ptr = ptr / "pi";
|
||||
CHECK(j[ptr] == j["pi"]);
|
||||
|
||||
ptr.pop_back();
|
||||
CHECK(j[ptr] == j);
|
||||
|
||||
// object and children access
|
||||
const std::string answer("answer");
|
||||
ptr /= answer;
|
||||
ptr = ptr / "everything";
|
||||
CHECK(j[ptr] == j["answer"]["everything"]);
|
||||
|
||||
ptr.pop_back();
|
||||
ptr.pop_back();
|
||||
CHECK(j[ptr] == j);
|
||||
|
||||
CHECK(ptr / ""_json_pointer == ptr);
|
||||
CHECK(j["/answer"_json_pointer / "/everything"_json_pointer] == j["answer"]["everything"]);
|
||||
|
||||
// list children access
|
||||
CHECK(j["/list"_json_pointer / 1] == j["list"][1]);
|
||||
|
||||
// push key which has to be encoded
|
||||
ptr /= "object";
|
||||
ptr = ptr / "/";
|
||||
CHECK(j[ptr] == j["object"]["/"]);
|
||||
CHECK(ptr.to_string() == "/object/~1");
|
||||
}
|
||||
}
|
||||
50
vendor/json/test/src/unit-large_json.cpp
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
TEST_CASE("tests on very large JSONs")
|
||||
{
|
||||
SECTION("issue #1419 - Segmentation fault (stack overflow) due to unbounded recursion")
|
||||
{
|
||||
const auto depth = 5000000;
|
||||
|
||||
std::string s(2 * depth, '[');
|
||||
std::fill(s.begin() + depth, s.end(), ']');
|
||||
|
||||
json _;
|
||||
CHECK_NOTHROW(_ = nlohmann::json::parse(s));
|
||||
}
|
||||
}
|
||||
|
||||
262
vendor/json/test/src/unit-merge_patch.cpp
vendored
Normal file
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
TEST_CASE("JSON Merge Patch")
|
||||
{
|
||||
SECTION("examples from RFC 7396")
|
||||
{
|
||||
SECTION("Section 1")
|
||||
{
|
||||
json document = R"({
|
||||
"a": "b",
|
||||
"c": {
|
||||
"d": "e",
|
||||
"f": "g"
|
||||
}
|
||||
})"_json;
|
||||
|
||||
json patch = R"({
|
||||
"a": "z",
|
||||
"c": {
|
||||
"f": null
|
||||
}
|
||||
})"_json;
|
||||
|
||||
json expected = R"({
|
||||
"a": "z",
|
||||
"c": {
|
||||
"d": "e"
|
||||
}
|
||||
})"_json;
|
||||
|
||||
document.merge_patch(patch);
|
||||
CHECK(document == expected);
|
||||
}
|
||||
|
||||
SECTION("Section 3")
|
||||
{
|
||||
json document = R"({
|
||||
"title": "Goodbye!",
|
||||
"author": {
|
||||
"givenName": "John",
|
||||
"familyName": "Doe"
|
||||
},
|
||||
"tags": [
|
||||
"example",
|
||||
"sample"
|
||||
],
|
||||
"content": "This will be unchanged"
|
||||
})"_json;
|
||||
|
||||
json patch = R"({
|
||||
"title": "Hello!",
|
||||
"phoneNumber": "+01-123-456-7890",
|
||||
"author": {
|
||||
"familyName": null
|
||||
},
|
||||
"tags": [
|
||||
"example"
|
||||
]
|
||||
})"_json;
|
||||
|
||||
json expected = R"({
|
||||
"title": "Hello!",
|
||||
"author": {
|
||||
"givenName": "John"
|
||||
},
|
||||
"tags": [
|
||||
"example"
|
||||
],
|
||||
"content": "This will be unchanged",
|
||||
"phoneNumber": "+01-123-456-7890"
|
||||
})"_json;
|
||||
|
||||
document.merge_patch(patch);
|
||||
CHECK(document == expected);
|
||||
}
|
||||
|
||||
SECTION("Appendix A")
|
||||
{
|
||||
SECTION("Example 1")
|
||||
{
|
||||
json original = R"({"a":"b"})"_json;
|
||||
json patch = R"({"a":"c"})"_json;
|
||||
json result = R"({"a":"c"})"_json;
|
||||
|
||||
original.merge_patch(patch);
|
||||
CHECK(original == result);
|
||||
}
|
||||
|
||||
SECTION("Example 2")
|
||||
{
|
||||
json original = R"({"a":"b"})"_json;
|
||||
json patch = R"({"b":"c"})"_json;
|
||||
json result = R"({"a":"b", "b":"c"})"_json;
|
||||
|
||||
original.merge_patch(patch);
|
||||
CHECK(original == result);
|
||||
}
|
||||
|
||||
SECTION("Example 3")
|
||||
{
|
||||
json original = R"({"a":"b"})"_json;
|
||||
json patch = R"({"a":null})"_json;
|
||||
json result = R"({})"_json;
|
||||
|
||||
original.merge_patch(patch);
|
||||
CHECK(original == result);
|
||||
}
|
||||
|
||||
SECTION("Example 4")
|
||||
{
|
||||
json original = R"({"a":"b","b":"c"})"_json;
|
||||
json patch = R"({"a":null})"_json;
|
||||
json result = R"({"b":"c"})"_json;
|
||||
|
||||
original.merge_patch(patch);
|
||||
CHECK(original == result);
|
||||
}
|
||||
|
||||
SECTION("Example 5")
|
||||
{
|
||||
json original = R"({"a":["b"]})"_json;
|
||||
json patch = R"({"a":"c"})"_json;
|
||||
json result = R"({"a":"c"})"_json;
|
||||
|
||||
original.merge_patch(patch);
|
||||
CHECK(original == result);
|
||||
}
|
||||
|
||||
SECTION("Example 6")
|
||||
{
|
||||
json original = R"({"a":"c"})"_json;
|
||||
json patch = R"({"a":["b"]})"_json;
|
||||
json result = R"({"a":["b"]})"_json;
|
||||
|
||||
original.merge_patch(patch);
|
||||
CHECK(original == result);
|
||||
}
|
||||
|
||||
SECTION("Example 7")
|
||||
{
|
||||
json original = R"({"a":{"b": "c"}})"_json;
|
||||
json patch = R"({"a":{"b":"d","c":null}})"_json;
|
||||
json result = R"({"a": {"b": "d"}})"_json;
|
||||
|
||||
original.merge_patch(patch);
|
||||
CHECK(original == result);
|
||||
}
|
||||
|
||||
SECTION("Example 8")
|
||||
{
|
||||
json original = R"({"a":[{"b":"c"}]})"_json;
|
||||
json patch = R"({"a":[1]})"_json;
|
||||
json result = R"({"a":[1]})"_json;
|
||||
|
||||
original.merge_patch(patch);
|
||||
CHECK(original == result);
|
||||
}
|
||||
|
||||
SECTION("Example 9")
|
||||
{
|
||||
json original = R"(["a","b"])"_json;
|
||||
json patch = R"(["c","d"])"_json;
|
||||
json result = R"(["c","d"])"_json;
|
||||
|
||||
original.merge_patch(patch);
|
||||
CHECK(original == result);
|
||||
}
|
||||
|
||||
SECTION("Example 10")
|
||||
{
|
||||
json original = R"({"a":"b"})"_json;
|
||||
json patch = R"(["c"])"_json;
|
||||
json result = R"(["c"])"_json;
|
||||
|
||||
original.merge_patch(patch);
|
||||
CHECK(original == result);
|
||||
}
|
||||
|
||||
SECTION("Example 11")
|
||||
{
|
||||
json original = R"({"a":"foo"})"_json;
|
||||
json patch = R"(null)"_json;
|
||||
json result = R"(null)"_json;
|
||||
|
||||
original.merge_patch(patch);
|
||||
CHECK(original == result);
|
||||
}
|
||||
|
||||
SECTION("Example 12")
|
||||
{
|
||||
json original = R"({"a":"foo"})"_json;
|
||||
json patch = R"("bar")"_json;
|
||||
json result = R"("bar")"_json;
|
||||
|
||||
original.merge_patch(patch);
|
||||
CHECK(original == result);
|
||||
}
|
||||
|
||||
SECTION("Example 13")
|
||||
{
|
||||
json original = R"({"e":null})"_json;
|
||||
json patch = R"({"a":1})"_json;
|
||||
json result = R"({"e":null,"a":1})"_json;
|
||||
|
||||
original.merge_patch(patch);
|
||||
CHECK(original == result);
|
||||
}
|
||||
|
||||
SECTION("Example 14")
|
||||
{
|
||||
json original = R"([1,2])"_json;
|
||||
json patch = R"({"a":"b","c":null})"_json;
|
||||
json result = R"({"a":"b"})"_json;
|
||||
|
||||
original.merge_patch(patch);
|
||||
CHECK(original == result);
|
||||
}
|
||||
|
||||
SECTION("Example 15")
|
||||
{
|
||||
json original = R"({})"_json;
|
||||
json patch = R"({"a":{"bb":{"ccc":null}}})"_json;
|
||||
json result = R"({"a":{"bb":{}}})"_json;
|
||||
|
||||
original.merge_patch(patch);
|
||||
CHECK(original == result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
57
vendor/json/test/src/unit-meta.cpp
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
TEST_CASE("version information")
|
||||
{
|
||||
SECTION("meta()")
|
||||
{
|
||||
json j = json::meta();
|
||||
|
||||
CHECK(j["name"] == "JSON for Modern C++");
|
||||
CHECK(j["copyright"] == "(C) 2013-2021 Niels Lohmann");
|
||||
CHECK(j["url"] == "https://github.com/nlohmann/json");
|
||||
CHECK(j["version"] == json(
|
||||
{
|
||||
{"string", "3.9.1"},
|
||||
{"major", 3},
|
||||
{"minor", 9},
|
||||
{"patch", 1}
|
||||
}));
|
||||
|
||||
CHECK(j.find("platform") != j.end());
|
||||
CHECK(j.at("compiler").find("family") != j.at("compiler").end());
|
||||
CHECK(j.at("compiler").find("version") != j.at("compiler").end());
|
||||
CHECK(j.at("compiler").find("c++") != j.at("compiler").end());
|
||||
}
|
||||
}
|
||||
1008
vendor/json/test/src/unit-modifiers.cpp
vendored
Normal file
1885
vendor/json/test/src/unit-msgpack.cpp
vendored
Normal file
97
vendor/json/test/src/unit-noexcept.cpp
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using nlohmann::json;
|
||||
|
||||
namespace
|
||||
{
|
||||
enum test
|
||||
{
|
||||
};
|
||||
|
||||
struct pod {};
|
||||
struct pod_bis {};
|
||||
|
||||
void to_json(json&, pod) noexcept;
|
||||
void to_json(json&, pod_bis);
|
||||
void from_json(const json&, pod) noexcept;
|
||||
void from_json(const json&, pod_bis);
|
||||
void to_json(json&, pod) noexcept {}
|
||||
void to_json(json&, pod_bis) {}
|
||||
void from_json(const json&, pod) noexcept {}
|
||||
void from_json(const json&, pod_bis) {}
|
||||
|
||||
static json* j = nullptr;
|
||||
|
||||
static_assert(noexcept(json{}), "");
|
||||
static_assert(noexcept(nlohmann::to_json(*j, 2)), "");
|
||||
static_assert(noexcept(nlohmann::to_json(*j, 2.5)), "");
|
||||
static_assert(noexcept(nlohmann::to_json(*j, true)), "");
|
||||
static_assert(noexcept(nlohmann::to_json(*j, test{})), "");
|
||||
static_assert(noexcept(nlohmann::to_json(*j, pod{})), "");
|
||||
static_assert(!noexcept(nlohmann::to_json(*j, pod_bis{})), "");
|
||||
static_assert(noexcept(json(2)), "");
|
||||
static_assert(noexcept(json(test{})), "");
|
||||
static_assert(noexcept(json(pod{})), "");
|
||||
static_assert(noexcept(j->get<pod>()), "");
|
||||
static_assert(!noexcept(j->get<pod_bis>()), "");
|
||||
static_assert(noexcept(json(pod{})), "");
|
||||
}
|
||||
|
||||
TEST_CASE("runtime checks")
|
||||
{
|
||||
SECTION("nothrow-copy-constructible exceptions")
|
||||
{
|
||||
// for ERR60-CPP (https://github.com/nlohmann/json/issues/531):
|
||||
// Exceptions should be nothrow-copy-constructible. However, compilers
|
||||
// treat std::runtime_exception differently in this regard. Therefore,
|
||||
// we can only demand nothrow-copy-constructibility for our exceptions
|
||||
// if std::runtime_exception is.
|
||||
CHECK(std::is_nothrow_copy_constructible<json::exception>::value == std::is_nothrow_copy_constructible<std::runtime_error>::value);
|
||||
CHECK(std::is_nothrow_copy_constructible<json::parse_error>::value == std::is_nothrow_copy_constructible<std::runtime_error>::value);
|
||||
CHECK(std::is_nothrow_copy_constructible<json::invalid_iterator>::value == std::is_nothrow_copy_constructible<std::runtime_error>::value);
|
||||
CHECK(std::is_nothrow_copy_constructible<json::type_error>::value == std::is_nothrow_copy_constructible<std::runtime_error>::value);
|
||||
CHECK(std::is_nothrow_copy_constructible<json::out_of_range>::value == std::is_nothrow_copy_constructible<std::runtime_error>::value);
|
||||
CHECK(std::is_nothrow_copy_constructible<json::other_error>::value == std::is_nothrow_copy_constructible<std::runtime_error>::value);
|
||||
}
|
||||
|
||||
SECTION("silence -Wunneeded-internal-declaration errors")
|
||||
{
|
||||
j = nullptr;
|
||||
json j2;
|
||||
to_json(j2, pod());
|
||||
to_json(j2, pod_bis());
|
||||
from_json(j2, pod());
|
||||
from_json(j2, pod_bis());
|
||||
}
|
||||
}
|
||||
93
vendor/json/test/src/unit-ordered_json.cpp
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
using nlohmann::ordered_json;
|
||||
|
||||
|
||||
TEST_CASE("ordered_json")
|
||||
{
|
||||
json j;
|
||||
ordered_json oj;
|
||||
|
||||
j["element3"] = 3;
|
||||
j["element1"] = 1;
|
||||
j["element2"] = 2;
|
||||
|
||||
oj["element3"] = 3;
|
||||
oj["element1"] = 1;
|
||||
oj["element2"] = 2;
|
||||
|
||||
CHECK(j.dump() == "{\"element1\":1,\"element2\":2,\"element3\":3}");
|
||||
CHECK(oj.dump() == "{\"element3\":3,\"element1\":1,\"element2\":2}");
|
||||
|
||||
CHECK(j == json(oj));
|
||||
CHECK(ordered_json(json(oj)) == ordered_json(j));
|
||||
|
||||
j.erase("element1");
|
||||
oj.erase("element1");
|
||||
|
||||
CHECK(j.dump() == "{\"element2\":2,\"element3\":3}");
|
||||
CHECK(oj.dump() == "{\"element3\":3,\"element2\":2}");
|
||||
|
||||
// remove again and nothing changes
|
||||
j.erase("element1");
|
||||
oj.erase("element1");
|
||||
|
||||
CHECK(j.dump() == "{\"element2\":2,\"element3\":3}");
|
||||
CHECK(oj.dump() == "{\"element3\":3,\"element2\":2}");
|
||||
|
||||
// There are no dup keys cause constructor calls emplace...
|
||||
json multi {{"z", 1}, {"m", 2}, {"m", 3}, {"y", 4}, {"m", 5}};
|
||||
CHECK(multi.size() == 3);
|
||||
CHECK(multi.dump() == "{\"m\":2,\"y\":4,\"z\":1}");
|
||||
|
||||
ordered_json multi_ordered {{"z", 1}, {"m", 2}, {"m", 3}, {"y", 4}, {"m", 5}};
|
||||
CHECK(multi_ordered.size() == 3);
|
||||
CHECK(multi_ordered.dump() == "{\"z\":1,\"m\":2,\"y\":4}");
|
||||
CHECK(multi_ordered.erase("m") == 1);
|
||||
CHECK(multi_ordered.dump() == "{\"z\":1,\"y\":4}");
|
||||
|
||||
// Ranged insert test.
|
||||
// It seems that values shouldn't be overwritten. Only new values are added
|
||||
json j1 {{"c", 1}, {"b", 2}, {"a", 3}};
|
||||
const json j2 {{"c", 77}, {"d", 42}, {"a", 4}};
|
||||
j1.insert( j2.cbegin(), j2.cend() );
|
||||
CHECK(j1.size() == 4);
|
||||
CHECK(j1.dump() == "{\"a\":3,\"b\":2,\"c\":1,\"d\":42}");
|
||||
|
||||
ordered_json oj1 {{"c", 1}, {"b", 2}, {"a", 3}};
|
||||
const ordered_json oj2 {{"c", 77}, {"d", 42}, {"a", 4}};
|
||||
oj1.insert( oj2.cbegin(), oj2.cend() );
|
||||
CHECK(oj1.size() == 4);
|
||||
CHECK(oj1.dump() == "{\"c\":1,\"b\":2,\"a\":3,\"d\":42}");
|
||||
}
|
||||
292
vendor/json/test/src/unit-ordered_map.cpp
vendored
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::ordered_map;
|
||||
|
||||
|
||||
TEST_CASE("ordered_map")
|
||||
{
|
||||
SECTION("constructor")
|
||||
{
|
||||
SECTION("constructor from iterator range")
|
||||
{
|
||||
std::map<std::string, std::string> m {{"eins", "one"}, {"zwei", "two"}, {"drei", "three"}};
|
||||
ordered_map<std::string, std::string> om(m.begin(), m.end());
|
||||
CHECK(om.size() == 3);
|
||||
}
|
||||
|
||||
SECTION("copy assignment")
|
||||
{
|
||||
std::map<std::string, std::string> m {{"eins", "one"}, {"zwei", "two"}, {"drei", "three"}};
|
||||
ordered_map<std::string, std::string> om(m.begin(), m.end());
|
||||
const auto com = om;
|
||||
CHECK(com.size() == 3);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("at")
|
||||
{
|
||||
std::map<std::string, std::string> m {{"eins", "one"}, {"zwei", "two"}, {"drei", "three"}};
|
||||
ordered_map<std::string, std::string> om(m.begin(), m.end());
|
||||
const auto com = om;
|
||||
|
||||
SECTION("with Key&&")
|
||||
{
|
||||
CHECK(om.at(std::string("eins")) == std::string("one"));
|
||||
CHECK(com.at(std::string("eins")) == std::string("one"));
|
||||
CHECK_THROWS_AS(om.at(std::string("vier")), std::out_of_range);
|
||||
CHECK_THROWS_AS(com.at(std::string("vier")), std::out_of_range);
|
||||
}
|
||||
|
||||
SECTION("with const Key&&")
|
||||
{
|
||||
const std::string eins = "eins";
|
||||
const std::string vier = "vier";
|
||||
CHECK(om.at(eins) == std::string("one"));
|
||||
CHECK(com.at(eins) == std::string("one"));
|
||||
CHECK_THROWS_AS(om.at(vier), std::out_of_range);
|
||||
CHECK_THROWS_AS(com.at(vier), std::out_of_range);
|
||||
}
|
||||
|
||||
SECTION("with string literal")
|
||||
{
|
||||
CHECK(om.at("eins") == std::string("one"));
|
||||
CHECK(com.at("eins") == std::string("one"));
|
||||
CHECK_THROWS_AS(om.at("vier"), std::out_of_range);
|
||||
CHECK_THROWS_AS(com.at("vier"), std::out_of_range);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("operator[]")
|
||||
{
|
||||
std::map<std::string, std::string> m {{"eins", "one"}, {"zwei", "two"}, {"drei", "three"}};
|
||||
ordered_map<std::string, std::string> om(m.begin(), m.end());
|
||||
const auto com = om;
|
||||
|
||||
SECTION("with Key&&")
|
||||
{
|
||||
CHECK(om[std::string("eins")] == std::string("one"));
|
||||
CHECK(com[std::string("eins")] == std::string("one"));
|
||||
|
||||
CHECK(om[std::string("vier")] == std::string(""));
|
||||
CHECK(om.size() == 4);
|
||||
}
|
||||
|
||||
SECTION("with const Key&&")
|
||||
{
|
||||
const std::string eins = "eins";
|
||||
const std::string vier = "vier";
|
||||
|
||||
CHECK(om[eins] == std::string("one"));
|
||||
CHECK(com[eins] == std::string("one"));
|
||||
|
||||
CHECK(om[vier] == std::string(""));
|
||||
CHECK(om.size() == 4);
|
||||
}
|
||||
|
||||
SECTION("with string literal")
|
||||
{
|
||||
CHECK(om["eins"] == std::string("one"));
|
||||
CHECK(com["eins"] == std::string("one"));
|
||||
|
||||
CHECK(om["vier"] == std::string(""));
|
||||
CHECK(om.size() == 4);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("erase")
|
||||
{
|
||||
ordered_map<std::string, std::string> om;
|
||||
om["eins"] = "one";
|
||||
om["zwei"] = "two";
|
||||
om["drei"] = "three";
|
||||
|
||||
{
|
||||
auto it = om.begin();
|
||||
CHECK(it->first == "eins");
|
||||
++it;
|
||||
CHECK(it->first == "zwei");
|
||||
++it;
|
||||
CHECK(it->first == "drei");
|
||||
++it;
|
||||
CHECK(it == om.end());
|
||||
}
|
||||
|
||||
SECTION("with Key&&")
|
||||
{
|
||||
CHECK(om.size() == 3);
|
||||
CHECK(om.erase(std::string("eins")) == 1);
|
||||
CHECK(om.size() == 2);
|
||||
CHECK(om.erase(std::string("vier")) == 0);
|
||||
CHECK(om.size() == 2);
|
||||
|
||||
auto it = om.begin();
|
||||
CHECK(it->first == "zwei");
|
||||
++it;
|
||||
CHECK(it->first == "drei");
|
||||
++it;
|
||||
CHECK(it == om.end());
|
||||
}
|
||||
|
||||
SECTION("with const Key&&")
|
||||
{
|
||||
const std::string eins = "eins";
|
||||
const std::string vier = "vier";
|
||||
CHECK(om.size() == 3);
|
||||
CHECK(om.erase(eins) == 1);
|
||||
CHECK(om.size() == 2);
|
||||
CHECK(om.erase(vier) == 0);
|
||||
CHECK(om.size() == 2);
|
||||
|
||||
auto it = om.begin();
|
||||
CHECK(it->first == "zwei");
|
||||
++it;
|
||||
CHECK(it->first == "drei");
|
||||
++it;
|
||||
CHECK(it == om.end());
|
||||
}
|
||||
|
||||
SECTION("with string literal")
|
||||
{
|
||||
CHECK(om.size() == 3);
|
||||
CHECK(om.erase("eins") == 1);
|
||||
CHECK(om.size() == 2);
|
||||
CHECK(om.erase("vier") == 0);
|
||||
CHECK(om.size() == 2);
|
||||
|
||||
auto it = om.begin();
|
||||
CHECK(it->first == "zwei");
|
||||
++it;
|
||||
CHECK(it->first == "drei");
|
||||
++it;
|
||||
CHECK(it == om.end());
|
||||
}
|
||||
|
||||
SECTION("with iterator")
|
||||
{
|
||||
CHECK(om.size() == 3);
|
||||
CHECK(om.begin()->first == "eins");
|
||||
CHECK(std::next(om.begin(), 1)->first == "zwei");
|
||||
CHECK(std::next(om.begin(), 2)->first == "drei");
|
||||
|
||||
auto it = om.erase(om.begin());
|
||||
CHECK(it->first == "zwei");
|
||||
CHECK(om.size() == 2);
|
||||
|
||||
auto it2 = om.begin();
|
||||
CHECK(it2->first == "zwei");
|
||||
++it2;
|
||||
CHECK(it2->first == "drei");
|
||||
++it2;
|
||||
CHECK(it2 == om.end());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("count")
|
||||
{
|
||||
ordered_map<std::string, std::string> om;
|
||||
om["eins"] = "one";
|
||||
om["zwei"] = "two";
|
||||
om["drei"] = "three";
|
||||
|
||||
const std::string eins("eins");
|
||||
const std::string vier("vier");
|
||||
CHECK(om.count("eins") == 1);
|
||||
CHECK(om.count(std::string("eins")) == 1);
|
||||
CHECK(om.count(eins) == 1);
|
||||
CHECK(om.count("vier") == 0);
|
||||
CHECK(om.count(std::string("vier")) == 0);
|
||||
CHECK(om.count(vier) == 0);
|
||||
}
|
||||
|
||||
SECTION("find")
|
||||
{
|
||||
ordered_map<std::string, std::string> om;
|
||||
om["eins"] = "one";
|
||||
om["zwei"] = "two";
|
||||
om["drei"] = "three";
|
||||
const auto com = om;
|
||||
|
||||
const std::string eins("eins");
|
||||
const std::string vier("vier");
|
||||
CHECK(om.find("eins") == om.begin());
|
||||
CHECK(om.find(std::string("eins")) == om.begin());
|
||||
CHECK(om.find(eins) == om.begin());
|
||||
CHECK(om.find("vier") == om.end());
|
||||
CHECK(om.find(std::string("vier")) == om.end());
|
||||
CHECK(om.find(vier) == om.end());
|
||||
|
||||
CHECK(com.find("eins") == com.begin());
|
||||
CHECK(com.find(std::string("eins")) == com.begin());
|
||||
CHECK(com.find(eins) == com.begin());
|
||||
CHECK(com.find("vier") == com.end());
|
||||
CHECK(com.find(std::string("vier")) == com.end());
|
||||
CHECK(com.find(vier) == com.end());
|
||||
}
|
||||
|
||||
SECTION("insert")
|
||||
{
|
||||
ordered_map<std::string, std::string> om;
|
||||
om["eins"] = "one";
|
||||
om["zwei"] = "two";
|
||||
om["drei"] = "three";
|
||||
|
||||
SECTION("const value_type&")
|
||||
{
|
||||
ordered_map<std::string, std::string>::value_type vt1 {"eins", "1"};
|
||||
ordered_map<std::string, std::string>::value_type vt4 {"vier", "four"};
|
||||
|
||||
auto res1 = om.insert(vt1);
|
||||
CHECK(res1.first == om.begin());
|
||||
CHECK(res1.second == false);
|
||||
CHECK(om.size() == 3);
|
||||
|
||||
auto res4 = om.insert(vt4);
|
||||
CHECK(res4.first == om.begin() + 3);
|
||||
CHECK(res4.second == true);
|
||||
CHECK(om.size() == 4);
|
||||
}
|
||||
|
||||
SECTION("value_type&&")
|
||||
{
|
||||
auto res1 = om.insert({"eins", "1"});
|
||||
CHECK(res1.first == om.begin());
|
||||
CHECK(res1.second == false);
|
||||
CHECK(om.size() == 3);
|
||||
|
||||
auto res4 = om.insert({"vier", "four"});
|
||||
CHECK(res4.first == om.begin() + 3);
|
||||
CHECK(res4.second == true);
|
||||
CHECK(om.size() == 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
500
vendor/json/test/src/unit-pointer_access.cpp
vendored
Normal file
@@ -0,0 +1,500 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
TEST_CASE("pointer access")
|
||||
{
|
||||
SECTION("pointer access to object_t")
|
||||
{
|
||||
using test_type = json::object_t;
|
||||
json value = {{"one", 1}, {"two", 2}};
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
CHECK(p1 == value.get_ptr<test_type*>());
|
||||
CHECK(*p1 == value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
CHECK(p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(*p2 == value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
CHECK(p3 == value.get_ptr<const test_type* const>());
|
||||
CHECK(*p3 == value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
CHECK(value.get_ptr<json::object_t*>() != nullptr);
|
||||
CHECK(value.get_ptr<json::array_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::string_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::boolean_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("pointer access to const object_t")
|
||||
{
|
||||
using test_type = const json::object_t;
|
||||
const json value = {{"one", 1}, {"two", 2}};
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
CHECK(p1 == value.get_ptr<test_type*>());
|
||||
CHECK(*p1 == value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
CHECK(p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(*p2 == value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
CHECK(p3 == value.get_ptr<const test_type* const>());
|
||||
CHECK(*p3 == value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
CHECK(value.get_ptr<const json::object_t*>() != nullptr);
|
||||
CHECK(value.get_ptr<const json::array_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::string_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("pointer access to array_t")
|
||||
{
|
||||
using test_type = json::array_t;
|
||||
json value = {1, 2, 3, 4};
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
CHECK(p1 == value.get_ptr<test_type*>());
|
||||
CHECK(*p1 == value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
CHECK(p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(*p2 == value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
CHECK(p3 == value.get_ptr<const test_type* const>());
|
||||
CHECK(*p3 == value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
CHECK(value.get_ptr<json::object_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::array_t*>() != nullptr);
|
||||
CHECK(value.get_ptr<json::string_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::boolean_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("pointer access to const array_t")
|
||||
{
|
||||
using test_type = const json::array_t;
|
||||
const json value = {1, 2, 3, 4};
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
CHECK(p1 == value.get_ptr<test_type*>());
|
||||
CHECK(*p1 == value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
CHECK(p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(*p2 == value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
CHECK(p3 == value.get_ptr<const test_type* const>());
|
||||
CHECK(*p3 == value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
CHECK(value.get_ptr<const json::object_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::array_t*>() != nullptr);
|
||||
CHECK(value.get_ptr<const json::string_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("pointer access to string_t")
|
||||
{
|
||||
using test_type = json::string_t;
|
||||
json value = "hello";
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
CHECK(p1 == value.get_ptr<test_type*>());
|
||||
CHECK(*p1 == value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
CHECK(p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(*p2 == value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
CHECK(p3 == value.get_ptr<const test_type* const>());
|
||||
CHECK(*p3 == value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
CHECK(value.get_ptr<json::object_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::array_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::string_t*>() != nullptr);
|
||||
CHECK(value.get_ptr<json::boolean_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("pointer access to const string_t")
|
||||
{
|
||||
using test_type = const json::string_t;
|
||||
const json value = "hello";
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
CHECK(p1 == value.get_ptr<test_type*>());
|
||||
CHECK(*p1 == value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
CHECK(p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(*p2 == value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
CHECK(p3 == value.get_ptr<const test_type* const>());
|
||||
CHECK(*p3 == value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
CHECK(value.get_ptr<const json::object_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::array_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::string_t*>() != nullptr);
|
||||
CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("pointer access to boolean_t")
|
||||
{
|
||||
using test_type = json::boolean_t;
|
||||
json value = false;
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
CHECK(p1 == value.get_ptr<test_type*>());
|
||||
CHECK(*p1 == value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
CHECK(p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(*p2 == value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
CHECK(p3 == value.get_ptr<const test_type* const>());
|
||||
CHECK(*p3 == value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
CHECK(value.get_ptr<json::object_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::array_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::string_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::boolean_t*>() != nullptr);
|
||||
CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("pointer access to const boolean_t")
|
||||
{
|
||||
using test_type = const json::boolean_t;
|
||||
const json value = false;
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
CHECK(p1 == value.get_ptr<test_type*>());
|
||||
//CHECK(*p1 == value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
CHECK(p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(*p2 == value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
CHECK(p3 == value.get_ptr<const test_type* const>());
|
||||
CHECK(*p3 == value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
CHECK(value.get_ptr<const json::object_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::array_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::string_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::boolean_t*>() != nullptr);
|
||||
CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("pointer access to number_integer_t")
|
||||
{
|
||||
using test_type = json::number_integer_t;
|
||||
json value = 23;
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
CHECK(p1 == value.get_ptr<test_type*>());
|
||||
CHECK(*p1 == value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
CHECK(p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(*p2 == value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
CHECK(p3 == value.get_ptr<const test_type* const>());
|
||||
CHECK(*p3 == value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
CHECK(value.get_ptr<json::object_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::array_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::string_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::boolean_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::number_integer_t*>() != nullptr);
|
||||
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("pointer access to const number_integer_t")
|
||||
{
|
||||
using test_type = const json::number_integer_t;
|
||||
const json value = 23;
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
CHECK(p1 == value.get_ptr<test_type*>());
|
||||
CHECK(*p1 == value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
CHECK(p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(*p2 == value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
CHECK(p3 == value.get_ptr<const test_type* const>());
|
||||
CHECK(*p3 == value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
CHECK(value.get_ptr<const json::object_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::array_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::string_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_integer_t*>() != nullptr);
|
||||
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("pointer access to number_unsigned_t")
|
||||
{
|
||||
using test_type = json::number_unsigned_t;
|
||||
json value = 23u;
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
CHECK(p1 == value.get_ptr<test_type*>());
|
||||
CHECK(*p1 == value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
CHECK(p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(*p2 == value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
CHECK(p3 == value.get_ptr<const test_type* const>());
|
||||
CHECK(*p3 == value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
CHECK(value.get_ptr<json::object_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::array_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::string_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::boolean_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::number_integer_t*>() != nullptr);
|
||||
CHECK(value.get_ptr<json::number_unsigned_t*>() != nullptr);
|
||||
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("pointer access to const number_unsigned_t")
|
||||
{
|
||||
using test_type = const json::number_unsigned_t;
|
||||
const json value = 23u;
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
CHECK(p1 == value.get_ptr<test_type*>());
|
||||
CHECK(*p1 == value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
CHECK(p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(*p2 == value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
CHECK(p3 == value.get_ptr<const test_type* const>());
|
||||
CHECK(*p3 == value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
CHECK(value.get_ptr<const json::object_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::array_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::string_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_integer_t*>() != nullptr);
|
||||
CHECK(value.get_ptr<const json::number_unsigned_t*>() != nullptr);
|
||||
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("pointer access to number_float_t")
|
||||
{
|
||||
using test_type = json::number_float_t;
|
||||
json value = 42.23;
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
CHECK(p1 == value.get_ptr<test_type*>());
|
||||
CHECK(*p1 == Approx(value.get<test_type>()));
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
CHECK(p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(*p2 == Approx(value.get<test_type>()));
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
CHECK(p3 == value.get_ptr<const test_type* const>());
|
||||
CHECK(*p3 == Approx(value.get<test_type>()));
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
CHECK(value.get_ptr<json::object_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::array_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::string_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::boolean_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::number_float_t*>() != nullptr);
|
||||
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("pointer access to const number_float_t")
|
||||
{
|
||||
using test_type = const json::number_float_t;
|
||||
const json value = 42.23;
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
CHECK(p1 == value.get_ptr<test_type*>());
|
||||
CHECK(*p1 == Approx(value.get<test_type>()));
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
CHECK(p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(*p2 == Approx(value.get<test_type>()));
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
CHECK(p3 == value.get_ptr<const test_type* const>());
|
||||
CHECK(*p3 == Approx(value.get<test_type>()));
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
CHECK(value.get_ptr<const json::object_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::array_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::string_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_float_t*>() != nullptr);
|
||||
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("pointer access to const binary_t")
|
||||
{
|
||||
using test_type = const json::binary_t;
|
||||
const json value = json::binary({1, 2, 3});
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
CHECK(p1 == value.get_ptr<test_type*>());
|
||||
CHECK(*p1 == value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
CHECK(p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(*p2 == value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
CHECK(p3 == value.get_ptr<const test_type* const>());
|
||||
CHECK(*p3 == value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
CHECK(value.get_ptr<const json::object_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::array_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::string_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::binary_t*>() != nullptr);
|
||||
}
|
||||
|
||||
SECTION("pointer access to const binary_t")
|
||||
{
|
||||
using test_type = const json::binary_t;
|
||||
const json value = json::binary({});
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
CHECK(p1 == value.get_ptr<test_type*>());
|
||||
CHECK(*p1 == value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
CHECK(p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(*p2 == value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
CHECK(p3 == value.get_ptr<const test_type* const>());
|
||||
CHECK(*p3 == value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
CHECK(value.get_ptr<const json::object_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::array_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::string_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::binary_t*>() != nullptr);
|
||||
}
|
||||
}
|
||||
327
vendor/json/test/src/unit-readme.cpp
vendored
Normal file
@@ -0,0 +1,327 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
DOCTEST_GCC_SUPPRESS_WARNING("-Wfloat-equal")
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
#include <deque>
|
||||
#include <forward_list>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable : 4189) // local variable is initialized but not referenced
|
||||
#endif
|
||||
|
||||
TEST_CASE("README" * doctest::skip())
|
||||
{
|
||||
{
|
||||
// redirect std::cout for the README file
|
||||
auto old_cout_buffer = std::cout.rdbuf();
|
||||
std::ostringstream new_stream;
|
||||
std::cout.rdbuf(new_stream.rdbuf());
|
||||
{
|
||||
// create an empty structure (null)
|
||||
json j;
|
||||
|
||||
// add a number that is stored as double (note the implicit conversion of j to an object)
|
||||
j["pi"] = 3.141;
|
||||
|
||||
// add a Boolean that is stored as bool
|
||||
j["happy"] = true;
|
||||
|
||||
// add a string that is stored as std::string
|
||||
j["name"] = "Niels";
|
||||
|
||||
// add another null object by passing nullptr
|
||||
j["nothing"] = nullptr;
|
||||
|
||||
// add an object inside the object
|
||||
j["answer"]["everything"] = 42;
|
||||
|
||||
// add an array that is stored as std::vector (using an initializer list)
|
||||
j["list"] = { 1, 0, 2 };
|
||||
|
||||
// add another object (using an initializer list of pairs)
|
||||
j["object"] = { {"currency", "USD"}, {"value", 42.99} };
|
||||
|
||||
// instead, you could also write (which looks very similar to the JSON above)
|
||||
json j2 =
|
||||
{
|
||||
{"pi", 3.141},
|
||||
{"happy", true},
|
||||
{"name", "Niels"},
|
||||
{"nothing", nullptr},
|
||||
{
|
||||
"answer", {
|
||||
{"everything", 42}
|
||||
}
|
||||
},
|
||||
{"list", {1, 0, 2}},
|
||||
{
|
||||
"object", {
|
||||
{"currency", "USD"},
|
||||
{"value", 42.99}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
{
|
||||
// ways to express the empty array []
|
||||
json empty_array_implicit = {{}};
|
||||
CHECK(empty_array_implicit.is_array());
|
||||
json empty_array_explicit = json::array();
|
||||
CHECK(empty_array_explicit.is_array());
|
||||
|
||||
// a way to express the empty object {}
|
||||
json empty_object_explicit = json::object();
|
||||
CHECK(empty_object_explicit.is_object());
|
||||
|
||||
// a way to express an _array_ of key/value pairs [["currency", "USD"], ["value", 42.99]]
|
||||
json array_not_object = json::array({ {"currency", "USD"}, {"value", 42.99} });
|
||||
CHECK(array_not_object.is_array());
|
||||
CHECK(array_not_object.size() == 2);
|
||||
CHECK(array_not_object[0].is_array());
|
||||
CHECK(array_not_object[1].is_array());
|
||||
}
|
||||
|
||||
{
|
||||
// create object from string literal
|
||||
json j = "{ \"happy\": true, \"pi\": 3.141 }"_json;
|
||||
|
||||
// or even nicer with a raw string literal
|
||||
auto j2 = R"(
|
||||
{
|
||||
"happy": true,
|
||||
"pi": 3.141
|
||||
}
|
||||
)"_json;
|
||||
|
||||
// or explicitly
|
||||
auto j3 = json::parse("{ \"happy\": true, \"pi\": 3.141 }");
|
||||
|
||||
// explicit conversion to string
|
||||
std::string s = j.dump(); // {\"happy\":true,\"pi\":3.141}
|
||||
|
||||
// serialization with pretty printing
|
||||
// pass in the amount of spaces to indent
|
||||
std::cout << j.dump(4) << std::endl;
|
||||
// {
|
||||
// "happy": true,
|
||||
// "pi": 3.141
|
||||
// }
|
||||
|
||||
std::cout << std::setw(2) << j << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
// create an array using push_back
|
||||
json j;
|
||||
j.push_back("foo");
|
||||
j.push_back(1);
|
||||
j.push_back(true);
|
||||
|
||||
// comparison
|
||||
bool x = (j == "[\"foo\", 1, true]"_json); // true
|
||||
CHECK(x == true);
|
||||
|
||||
// iterate the array
|
||||
for (json::iterator it = j.begin(); it != j.end(); ++it)
|
||||
{
|
||||
std::cout << *it << '\n';
|
||||
}
|
||||
|
||||
// range-based for
|
||||
for (auto element : j)
|
||||
{
|
||||
std::cout << element << '\n';
|
||||
}
|
||||
|
||||
// getter/setter
|
||||
const auto tmp = j[0].get<std::string>();
|
||||
j[1] = 42;
|
||||
bool foo{j.at(2)};
|
||||
CHECK(foo == true);
|
||||
|
||||
// other stuff
|
||||
j.size(); // 3 entries
|
||||
j.empty(); // false
|
||||
j.type(); // json::value_t::array
|
||||
j.clear(); // the array is empty again
|
||||
|
||||
// create an object
|
||||
json o;
|
||||
o["foo"] = 23;
|
||||
o["bar"] = false;
|
||||
o["baz"] = 3.141;
|
||||
|
||||
// find an entry
|
||||
if (o.find("foo") != o.end())
|
||||
{
|
||||
// there is an entry with key "foo"
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<int> c_vector {1, 2, 3, 4};
|
||||
json j_vec(c_vector);
|
||||
// [1, 2, 3, 4]
|
||||
|
||||
std::deque<float> c_deque {1.2f, 2.3f, 3.4f, 5.6f};
|
||||
json j_deque(c_deque);
|
||||
// [1.2, 2.3, 3.4, 5.6]
|
||||
|
||||
std::list<bool> c_list {true, true, false, true};
|
||||
json j_list(c_list);
|
||||
// [true, true, false, true]
|
||||
|
||||
std::forward_list<int64_t> c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543};
|
||||
json j_flist(c_flist);
|
||||
// [12345678909876, 23456789098765, 34567890987654, 45678909876543]
|
||||
|
||||
std::array<unsigned long, 4> c_array {{1, 2, 3, 4}};
|
||||
json j_array(c_array);
|
||||
// [1, 2, 3, 4]
|
||||
|
||||
std::set<std::string> c_set {"one", "two", "three", "four", "one"};
|
||||
json j_set(c_set); // only one entry for "one" is used
|
||||
// ["four", "one", "three", "two"]
|
||||
|
||||
std::unordered_set<std::string> c_uset {"one", "two", "three", "four", "one"};
|
||||
json j_uset(c_uset); // only one entry for "one" is used
|
||||
// maybe ["two", "three", "four", "one"]
|
||||
|
||||
std::multiset<std::string> c_mset {"one", "two", "one", "four"};
|
||||
json j_mset(c_mset); // both entries for "one" are used
|
||||
// maybe ["one", "two", "one", "four"]
|
||||
|
||||
std::unordered_multiset<std::string> c_umset {"one", "two", "one", "four"};
|
||||
json j_umset(c_umset); // both entries for "one" are used
|
||||
// maybe ["one", "two", "one", "four"]
|
||||
}
|
||||
|
||||
{
|
||||
std::map<std::string, int> c_map { {"one", 1}, {"two", 2}, {"three", 3} };
|
||||
json j_map(c_map);
|
||||
// {"one": 1, "two": 2, "three": 3}
|
||||
|
||||
std::unordered_map<const char*, float> c_umap { {"one", 1.2f}, {"two", 2.3f}, {"three", 3.4f} };
|
||||
json j_umap(c_umap);
|
||||
// {"one": 1.2, "two": 2.3, "three": 3.4}
|
||||
|
||||
std::multimap<std::string, bool> c_mmap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };
|
||||
json j_mmap(c_mmap); // only one entry for key "three" is used
|
||||
// maybe {"one": true, "two": true, "three": true}
|
||||
|
||||
std::unordered_multimap<std::string, bool> c_ummap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };
|
||||
json j_ummap(c_ummap); // only one entry for key "three" is used
|
||||
// maybe {"one": true, "two": true, "three": true}
|
||||
}
|
||||
|
||||
{
|
||||
// strings
|
||||
std::string s1 = "Hello, world!";
|
||||
json js = s1;
|
||||
auto s2 = js.get<std::string>();
|
||||
|
||||
// Booleans
|
||||
bool b1 = true;
|
||||
json jb = b1;
|
||||
bool b2{jb};
|
||||
CHECK(b2 == true);
|
||||
|
||||
// numbers
|
||||
int i = 42;
|
||||
json jn = i;
|
||||
double f{jn};
|
||||
CHECK(f == 42);
|
||||
|
||||
// etc.
|
||||
|
||||
std::string vs = js.get<std::string>();
|
||||
bool vb = jb.get<bool>();
|
||||
CHECK(vb == true);
|
||||
int vi = jn.get<int>();
|
||||
CHECK(vi == 42);
|
||||
|
||||
// etc.
|
||||
}
|
||||
|
||||
{
|
||||
// a JSON value
|
||||
json j_original = R"({
|
||||
"baz": ["one", "two", "three"],
|
||||
"foo": "bar"
|
||||
})"_json;
|
||||
|
||||
// access members with a JSON pointer (RFC 6901)
|
||||
j_original["/baz/1"_json_pointer];
|
||||
// "two"
|
||||
|
||||
// a JSON patch (RFC 6902)
|
||||
json j_patch = R"([
|
||||
{ "op": "replace", "path": "/baz", "value": "boo" },
|
||||
{ "op": "add", "path": "/hello", "value": ["world"] },
|
||||
{ "op": "remove", "path": "/foo"}
|
||||
])"_json;
|
||||
|
||||
// apply the patch
|
||||
json j_result = j_original.patch(j_patch);
|
||||
// {
|
||||
// "baz": "boo",
|
||||
// "hello": ["world"]
|
||||
// }
|
||||
|
||||
// calculate a JSON patch from two JSON values
|
||||
auto res = json::diff(j_result, j_original);
|
||||
// [
|
||||
// { "op":" replace", "path": "/baz", "value": ["one", "two", "three"] },
|
||||
// { "op":"remove","path":"/hello" },
|
||||
// { "op":"add","path":"/foo","value":"bar" }
|
||||
// ]
|
||||
}
|
||||
|
||||
// restore old std::cout
|
||||
std::cout.rdbuf(old_cout_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
318
vendor/json/test/src/unit-reference_access.cpp
vendored
Normal file
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
DOCTEST_GCC_SUPPRESS_WARNING("-Wfloat-equal")
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
TEST_CASE("reference access")
|
||||
{
|
||||
// create a JSON value with different types
|
||||
json json_types =
|
||||
{
|
||||
{"boolean", true},
|
||||
{
|
||||
"number", {
|
||||
{"integer", 42},
|
||||
{"floating-point", 17.23}
|
||||
}
|
||||
},
|
||||
{"string", "Hello, world!"},
|
||||
{"array", {1, 2, 3, 4, 5}},
|
||||
{"null", nullptr}
|
||||
};
|
||||
|
||||
SECTION("reference access to object_t")
|
||||
{
|
||||
using test_type = json::object_t;
|
||||
json value = {{"one", 1}, {"two", 2}};
|
||||
|
||||
// check if references are returned correctly
|
||||
test_type& p1 = value.get_ref<test_type&>();
|
||||
CHECK(&p1 == value.get_ptr<test_type*>());
|
||||
CHECK(p1 == value.get<test_type>());
|
||||
|
||||
const test_type& p2 = value.get_ref<const test_type&>();
|
||||
CHECK(&p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(p2 == value.get<test_type>());
|
||||
|
||||
// check if mismatching references throw correctly
|
||||
CHECK_NOTHROW(value.get_ref<json::object_t&>());
|
||||
CHECK_THROWS_AS(value.get_ref<json::array_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::array_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object");
|
||||
CHECK_THROWS_AS(value.get_ref<json::string_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::string_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object");
|
||||
CHECK_THROWS_AS(value.get_ref<json::boolean_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::boolean_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object");
|
||||
CHECK_THROWS_AS(value.get_ref<json::number_integer_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::number_integer_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object");
|
||||
CHECK_THROWS_AS(value.get_ref<json::number_unsigned_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::number_unsigned_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object");
|
||||
CHECK_THROWS_AS(value.get_ref<json::number_float_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::number_float_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object");
|
||||
}
|
||||
|
||||
SECTION("const reference access to const object_t")
|
||||
{
|
||||
using test_type = json::object_t;
|
||||
const json value = {{"one", 1}, {"two", 2}};
|
||||
|
||||
// this should not compile
|
||||
// test_type& p1 = value.get_ref<test_type&>();
|
||||
|
||||
// check if references are returned correctly
|
||||
const test_type& p2 = value.get_ref<const test_type&>();
|
||||
CHECK(&p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(p2 == value.get<test_type>());
|
||||
}
|
||||
|
||||
SECTION("reference access to array_t")
|
||||
{
|
||||
using test_type = json::array_t;
|
||||
json value = {1, 2, 3, 4};
|
||||
|
||||
// check if references are returned correctly
|
||||
test_type& p1 = value.get_ref<test_type&>();
|
||||
CHECK(&p1 == value.get_ptr<test_type*>());
|
||||
CHECK(p1 == value.get<test_type>());
|
||||
|
||||
const test_type& p2 = value.get_ref<const test_type&>();
|
||||
CHECK(&p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(p2 == value.get<test_type>());
|
||||
|
||||
// check if mismatching references throw correctly
|
||||
CHECK_THROWS_AS(value.get_ref<json::object_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::object_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array");
|
||||
CHECK_NOTHROW(value.get_ref<json::array_t&>());
|
||||
CHECK_THROWS_AS(value.get_ref<json::string_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::string_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array");
|
||||
CHECK_THROWS_AS(value.get_ref<json::boolean_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::boolean_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array");
|
||||
CHECK_THROWS_AS(value.get_ref<json::number_integer_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::number_integer_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array");
|
||||
CHECK_THROWS_AS(value.get_ref<json::number_unsigned_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::number_unsigned_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array");
|
||||
CHECK_THROWS_AS(value.get_ref<json::number_float_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::number_float_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is array");
|
||||
}
|
||||
|
||||
SECTION("reference access to string_t")
|
||||
{
|
||||
using test_type = json::string_t;
|
||||
json value = "hello";
|
||||
|
||||
// check if references are returned correctly
|
||||
test_type& p1 = value.get_ref<test_type&>();
|
||||
CHECK(&p1 == value.get_ptr<test_type*>());
|
||||
CHECK(p1 == value.get<test_type>());
|
||||
|
||||
const test_type& p2 = value.get_ref<const test_type&>();
|
||||
CHECK(&p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(p2 == value.get<test_type>());
|
||||
|
||||
// check if mismatching references throw correctly
|
||||
CHECK_THROWS_AS(value.get_ref<json::object_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::object_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string");
|
||||
CHECK_THROWS_AS(value.get_ref<json::array_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::array_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string");
|
||||
CHECK_NOTHROW(value.get_ref<json::string_t&>());
|
||||
CHECK_THROWS_AS(value.get_ref<json::boolean_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::boolean_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string");
|
||||
CHECK_THROWS_AS(value.get_ref<json::number_integer_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::number_integer_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string");
|
||||
CHECK_THROWS_AS(value.get_ref<json::number_unsigned_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::number_unsigned_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string");
|
||||
CHECK_THROWS_AS(value.get_ref<json::number_float_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::number_float_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is string");
|
||||
}
|
||||
|
||||
SECTION("reference access to boolean_t")
|
||||
{
|
||||
using test_type = json::boolean_t;
|
||||
json value = false;
|
||||
|
||||
// check if references are returned correctly
|
||||
test_type& p1 = value.get_ref<test_type&>();
|
||||
CHECK(&p1 == value.get_ptr<test_type*>());
|
||||
CHECK(p1 == value.get<test_type>());
|
||||
|
||||
const test_type& p2 = value.get_ref<const test_type&>();
|
||||
CHECK(&p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(p2 == value.get<test_type>());
|
||||
|
||||
// check if mismatching references throw correctly
|
||||
CHECK_THROWS_AS(value.get_ref<json::object_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::object_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean");
|
||||
CHECK_THROWS_AS(value.get_ref<json::array_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::array_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean");
|
||||
CHECK_THROWS_AS(value.get_ref<json::string_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::string_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean");
|
||||
CHECK_NOTHROW(value.get_ref<json::boolean_t&>());
|
||||
CHECK_THROWS_AS(value.get_ref<json::number_integer_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::number_integer_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean");
|
||||
CHECK_THROWS_AS(value.get_ref<json::number_unsigned_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::number_unsigned_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean");
|
||||
CHECK_THROWS_AS(value.get_ref<json::number_float_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::number_float_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is boolean");
|
||||
}
|
||||
|
||||
SECTION("reference access to number_integer_t")
|
||||
{
|
||||
using test_type = json::number_integer_t;
|
||||
json value = -23;
|
||||
|
||||
// check if references are returned correctly
|
||||
test_type& p1 = value.get_ref<test_type&>();
|
||||
CHECK(&p1 == value.get_ptr<test_type*>());
|
||||
CHECK(p1 == value.get<test_type>());
|
||||
|
||||
const test_type& p2 = value.get_ref<const test_type&>();
|
||||
CHECK(&p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(p2 == value.get<test_type>());
|
||||
|
||||
// check if mismatching references throw correctly
|
||||
CHECK_THROWS_AS(value.get_ref<json::object_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::object_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
|
||||
CHECK_THROWS_AS(value.get_ref<json::array_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::array_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
|
||||
CHECK_THROWS_AS(value.get_ref<json::string_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::string_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
|
||||
CHECK_THROWS_AS(value.get_ref<json::boolean_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::boolean_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
|
||||
CHECK_NOTHROW(value.get_ref<json::number_integer_t&>());
|
||||
CHECK_THROWS_AS(value.get_ref<json::number_unsigned_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::number_unsigned_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
|
||||
CHECK_THROWS_AS(value.get_ref<json::number_float_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::number_float_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
|
||||
}
|
||||
|
||||
SECTION("reference access to number_unsigned_t")
|
||||
{
|
||||
using test_type = json::number_unsigned_t;
|
||||
json value = 23u;
|
||||
|
||||
// check if references are returned correctly
|
||||
test_type& p1 = value.get_ref<test_type&>();
|
||||
CHECK(&p1 == value.get_ptr<test_type*>());
|
||||
CHECK(p1 == value.get<test_type>());
|
||||
|
||||
const test_type& p2 = value.get_ref<const test_type&>();
|
||||
CHECK(&p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(p2 == value.get<test_type>());
|
||||
|
||||
// check if mismatching references throw correctly
|
||||
CHECK_THROWS_AS(value.get_ref<json::object_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::object_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
|
||||
CHECK_THROWS_AS(value.get_ref<json::array_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::array_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
|
||||
CHECK_THROWS_AS(value.get_ref<json::string_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::string_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
|
||||
CHECK_THROWS_AS(value.get_ref<json::boolean_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::boolean_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
|
||||
//CHECK_THROWS_AS(value.get_ref<json::number_integer_t&>(), json::type_error&);
|
||||
//CHECK_THROWS_WITH(value.get_ref<json::number_integer_t&>(),
|
||||
// "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
|
||||
CHECK_NOTHROW(value.get_ref<json::number_unsigned_t&>());
|
||||
CHECK_THROWS_AS(value.get_ref<json::number_float_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::number_float_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
|
||||
}
|
||||
|
||||
SECTION("reference access to number_float_t")
|
||||
{
|
||||
using test_type = json::number_float_t;
|
||||
json value = 42.23;
|
||||
|
||||
// check if references are returned correctly
|
||||
test_type& p1 = value.get_ref<test_type&>();
|
||||
CHECK(&p1 == value.get_ptr<test_type*>());
|
||||
CHECK(p1 == value.get<test_type>());
|
||||
|
||||
const test_type& p2 = value.get_ref<const test_type&>();
|
||||
CHECK(&p2 == value.get_ptr<const test_type*>());
|
||||
CHECK(p2 == value.get<test_type>());
|
||||
|
||||
// check if mismatching references throw correctly
|
||||
CHECK_THROWS_AS(value.get_ref<json::object_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::object_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
|
||||
CHECK_THROWS_AS(value.get_ref<json::array_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::array_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
|
||||
CHECK_THROWS_AS(value.get_ref<json::string_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::string_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
|
||||
CHECK_THROWS_AS(value.get_ref<json::boolean_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::boolean_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
|
||||
CHECK_THROWS_AS(value.get_ref<json::number_integer_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::number_integer_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
|
||||
CHECK_THROWS_AS(value.get_ref<json::number_unsigned_t&>(), json::type_error&);
|
||||
CHECK_THROWS_WITH(value.get_ref<json::number_unsigned_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number");
|
||||
CHECK_NOTHROW(value.get_ref<json::number_float_t&>());
|
||||
}
|
||||
}
|
||||
1613
vendor/json/test/src/unit-regression1.cpp
vendored
Normal file
501
vendor/json/test/src/unit-regression2.cpp
vendored
Normal file
@@ -0,0 +1,501 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
DOCTEST_GCC_SUPPRESS_WARNING("-Wfloat-equal")
|
||||
|
||||
// for some reason including this after the json header leads to linker errors with VS 2017...
|
||||
#include <locale>
|
||||
|
||||
#define JSON_TESTS_PRIVATE
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <list>
|
||||
#include <cstdio>
|
||||
#include <test_data.hpp>
|
||||
|
||||
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
|
||||
#define JSON_HAS_CPP_17
|
||||
#endif
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
#include <variant>
|
||||
#endif
|
||||
|
||||
#ifdef JSON_HAS_CPP_20
|
||||
#include <span>
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// for #1021
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
using float_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, float>;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// for #1647
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
namespace
|
||||
{
|
||||
struct NonDefaultFromJsonStruct { };
|
||||
|
||||
inline bool operator== (NonDefaultFromJsonStruct const&, NonDefaultFromJsonStruct const&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
enum class for_1647 { one, two };
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(for_1647,
|
||||
{
|
||||
{for_1647::one, "one"},
|
||||
{for_1647::two, "two"},
|
||||
})
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// for #1299
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Data
|
||||
{
|
||||
Data() = default;
|
||||
Data(const std::string& a_, const std::string b_) : a(a_), b(b_) {}
|
||||
std::string a {};
|
||||
std::string b {};
|
||||
};
|
||||
|
||||
void from_json(const json& j, Data& data)
|
||||
{
|
||||
j["a"].get_to(data.a);
|
||||
j["b"].get_to(data.b);
|
||||
}
|
||||
|
||||
bool operator==(Data const& lhs, Data const& rhs)
|
||||
{
|
||||
return lhs.a == rhs.a && lhs.b == rhs.b;
|
||||
}
|
||||
|
||||
//bool operator!=(Data const& lhs, Data const& rhs)
|
||||
//{
|
||||
// return !(lhs == rhs);
|
||||
//}
|
||||
|
||||
namespace nlohmann
|
||||
{
|
||||
template <>
|
||||
struct adl_serializer<NonDefaultFromJsonStruct>
|
||||
{
|
||||
static NonDefaultFromJsonStruct from_json (json const&) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// for #1805
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct NotSerializableData
|
||||
{
|
||||
int mydata;
|
||||
float myfloat;
|
||||
};
|
||||
|
||||
|
||||
TEST_CASE("regression tests 2")
|
||||
{
|
||||
SECTION("issue #1001 - Fix memory leak during parser callback")
|
||||
{
|
||||
auto geojsonExample = R"(
|
||||
{ "type": "FeatureCollection",
|
||||
"features": [
|
||||
{ "type": "Feature",
|
||||
"geometry": {"type": "Point", "coordinates": [102.0, 0.5]},
|
||||
"properties": {"prop0": "value0"}
|
||||
},
|
||||
{ "type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"prop0": "value0",
|
||||
"prop1": 0.0
|
||||
}
|
||||
},
|
||||
{ "type": "Feature",
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0],
|
||||
[100.0, 1.0], [100.0, 0.0] ]
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"prop0": "value0",
|
||||
"prop1": {"this": "that"}
|
||||
}
|
||||
}
|
||||
]
|
||||
})";
|
||||
|
||||
json::parser_callback_t cb = [&](int, json::parse_event_t event, json & parsed)
|
||||
{
|
||||
// skip uninteresting events
|
||||
if (event == json::parse_event_t::value && !parsed.is_primitive())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case json::parse_event_t::key:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
case json::parse_event_t::value:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
case json::parse_event_t::object_start:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
case json::parse_event_t::object_end:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
case json::parse_event_t::array_start:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
case json::parse_event_t::array_end:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto j = json::parse(geojsonExample, cb, true);
|
||||
CHECK(j == json());
|
||||
}
|
||||
|
||||
SECTION("issue #1021 - to/from_msgpack only works with standard typization")
|
||||
{
|
||||
float_json j = 1000.0;
|
||||
CHECK(float_json::from_cbor(float_json::to_cbor(j)) == j);
|
||||
CHECK(float_json::from_msgpack(float_json::to_msgpack(j)) == j);
|
||||
CHECK(float_json::from_ubjson(float_json::to_ubjson(j)) == j);
|
||||
|
||||
float_json j2 = {1000.0, 2000.0, 3000.0};
|
||||
CHECK(float_json::from_ubjson(float_json::to_ubjson(j2, true, true)) == j2);
|
||||
}
|
||||
|
||||
SECTION("issue #1045 - Using STL algorithms with JSON containers with expected results?")
|
||||
{
|
||||
json diffs = nlohmann::json::array();
|
||||
json m1{{"key1", 42}};
|
||||
json m2{{"key2", 42}};
|
||||
auto p1 = m1.items();
|
||||
auto p2 = m2.items();
|
||||
|
||||
using it_type = decltype(p1.begin());
|
||||
|
||||
std::set_difference(
|
||||
p1.begin(), p1.end(),
|
||||
p2.begin(), p2.end(),
|
||||
std::inserter(diffs, diffs.end()), [&](const it_type & e1, const it_type & e2) -> bool
|
||||
{
|
||||
using comper_pair = std::pair<std::string, decltype(e1.value())>; // Trying to avoid unneeded copy
|
||||
return comper_pair(e1.key(), e1.value()) < comper_pair(e2.key(), e2.value()); // Using pair comper
|
||||
});
|
||||
|
||||
CHECK(diffs.size() == 1); // Note the change here, was 2
|
||||
}
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
SECTION("issue #1292 - Serializing std::variant causes stack overflow")
|
||||
{
|
||||
static_assert(
|
||||
!std::is_constructible<json, std::variant<int, float>>::value, "");
|
||||
}
|
||||
#endif
|
||||
|
||||
SECTION("issue #1299 - compile error in from_json converting to container "
|
||||
"with std::pair")
|
||||
{
|
||||
json j =
|
||||
{
|
||||
{"1", {{"a", "testa_1"}, {"b", "testb_1"}}},
|
||||
{"2", {{"a", "testa_2"}, {"b", "testb_2"}}},
|
||||
{"3", {{"a", "testa_3"}, {"b", "testb_3"}}},
|
||||
};
|
||||
|
||||
std::map<std::string, Data> expected
|
||||
{
|
||||
{"1", {"testa_1", "testb_1"}},
|
||||
{"2", {"testa_2", "testb_2"}},
|
||||
{"3", {"testa_3", "testb_3"}},
|
||||
};
|
||||
const auto data = j.get<decltype(expected)>();
|
||||
CHECK(expected == data);
|
||||
}
|
||||
|
||||
SECTION("issue #1445 - buffer overflow in dumping invalid utf-8 strings")
|
||||
{
|
||||
SECTION("a bunch of -1, ensure_ascii=true")
|
||||
{
|
||||
const auto length = 300;
|
||||
|
||||
json dump_test;
|
||||
dump_test["1"] = std::string(length, -1);
|
||||
|
||||
std::string expected = "{\"1\":\"";
|
||||
for (int i = 0; i < length; ++i)
|
||||
{
|
||||
expected += "\\ufffd";
|
||||
}
|
||||
expected += "\"}";
|
||||
|
||||
auto s = dump_test.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);
|
||||
CHECK(s == expected);
|
||||
}
|
||||
SECTION("a bunch of -2, ensure_ascii=false")
|
||||
{
|
||||
const auto length = 500;
|
||||
|
||||
json dump_test;
|
||||
dump_test["1"] = std::string(length, -2);
|
||||
|
||||
std::string expected = "{\"1\":\"";
|
||||
for (int i = 0; i < length; ++i)
|
||||
{
|
||||
expected += "\xEF\xBF\xBD";
|
||||
}
|
||||
expected += "\"}";
|
||||
|
||||
auto s = dump_test.dump(-1, ' ', false, nlohmann::json::error_handler_t::replace);
|
||||
CHECK(s == expected);
|
||||
}
|
||||
SECTION("test case in issue #1445")
|
||||
{
|
||||
nlohmann::json dump_test;
|
||||
const int data[] =
|
||||
{
|
||||
109, 108, 103, 125, -122, -53, 115,
|
||||
18, 3, 0, 102, 19, 1, 15,
|
||||
-110, 13, -3, -1, -81, 32, 2,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
8, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, -80, 2,
|
||||
0, 0, 96, -118, 46, -116, 46,
|
||||
109, -84, -87, 108, 14, 109, -24,
|
||||
-83, 13, -18, -51, -83, -52, -115,
|
||||
14, 6, 32, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
64, 3, 0, 0, 0, 35, -74,
|
||||
-73, 55, 57, -128, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 33, 0, 0, 0, -96,
|
||||
-54, -28, -26
|
||||
};
|
||||
std::string s;
|
||||
for (unsigned i = 0; i < sizeof(data) / sizeof(int); i++)
|
||||
{
|
||||
s += static_cast<char>(data[i]);
|
||||
}
|
||||
dump_test["1"] = s;
|
||||
dump_test.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("issue #1447 - Integer Overflow (OSS-Fuzz 12506)")
|
||||
{
|
||||
json j = json::parse("[-9223372036854775808]");
|
||||
CHECK(j.dump() == "[-9223372036854775808]");
|
||||
}
|
||||
|
||||
SECTION("issue #1708 - minimum value of int64_t can be outputted")
|
||||
{
|
||||
constexpr auto smallest = (std::numeric_limits<int64_t>::min)();
|
||||
json j = smallest;
|
||||
CHECK(j.dump() == std::to_string(smallest));
|
||||
}
|
||||
|
||||
SECTION("issue #1727 - Contains with non-const lvalue json_pointer picks the wrong overload")
|
||||
{
|
||||
json j = {{"root", {{"settings", {{"logging", true}}}}}};
|
||||
|
||||
auto jptr1 = "/root/settings/logging"_json_pointer;
|
||||
auto jptr2 = json::json_pointer{"/root/settings/logging"};
|
||||
|
||||
CHECK(j.contains(jptr1));
|
||||
CHECK(j.contains(jptr2));
|
||||
}
|
||||
|
||||
SECTION("issue #1647 - compile error when deserializing enum if both non-default from_json and non-member operator== exists for other type")
|
||||
{
|
||||
{
|
||||
json j;
|
||||
NonDefaultFromJsonStruct x(j);
|
||||
NonDefaultFromJsonStruct y;
|
||||
CHECK(x == y);
|
||||
}
|
||||
|
||||
auto val = nlohmann::json("one").get<for_1647>();
|
||||
CHECK(val == for_1647::one);
|
||||
json j = val;
|
||||
}
|
||||
|
||||
SECTION("issue #1715 - json::from_cbor does not respect allow_exceptions = false when input is string literal")
|
||||
{
|
||||
SECTION("string literal")
|
||||
{
|
||||
json cbor = json::from_cbor("B", true, false);
|
||||
CHECK(cbor.is_discarded());
|
||||
}
|
||||
|
||||
SECTION("string array")
|
||||
{
|
||||
const char input[] = { 'B', 0x00 };
|
||||
json cbor = json::from_cbor(input, true, false);
|
||||
CHECK(cbor.is_discarded());
|
||||
}
|
||||
|
||||
SECTION("std::string")
|
||||
{
|
||||
json cbor = json::from_cbor(std::string("B"), true, false);
|
||||
CHECK(cbor.is_discarded());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("issue #1805 - A pair<T1, T2> is json constructible only if T1 and T2 are json constructible")
|
||||
{
|
||||
static_assert(!std::is_constructible<json, std::pair<std::string, NotSerializableData>>::value, "");
|
||||
static_assert(!std::is_constructible<json, std::pair<NotSerializableData, std::string>>::value, "");
|
||||
static_assert(std::is_constructible<json, std::pair<int, std::string>>::value, "");
|
||||
}
|
||||
SECTION("issue #1825 - A tuple<Args..> is json constructible only if all T in Args are json constructible")
|
||||
{
|
||||
static_assert(!std::is_constructible<json, std::tuple<std::string, NotSerializableData>>::value, "");
|
||||
static_assert(!std::is_constructible<json, std::tuple<NotSerializableData, std::string>>::value, "");
|
||||
static_assert(std::is_constructible<json, std::tuple<int, std::string>>::value, "");
|
||||
}
|
||||
|
||||
SECTION("issue #1983 - JSON patch diff for op=add formation is not as per standard (RFC 6902)")
|
||||
{
|
||||
const auto source = R"({ "foo": [ "1", "2" ] })"_json;
|
||||
const auto target = R"({"foo": [ "1", "2", "3" ]})"_json;
|
||||
const auto result = json::diff(source, target);
|
||||
CHECK(result.dump() == R"([{"op":"add","path":"/foo/-","value":"3"}])");
|
||||
}
|
||||
|
||||
SECTION("issue #2067 - cannot serialize binary data to text JSON")
|
||||
{
|
||||
const unsigned char data[] = {0x81, 0xA4, 0x64, 0x61, 0x74, 0x61, 0xC4, 0x0F, 0x33, 0x30, 0x30, 0x32, 0x33, 0x34, 0x30, 0x31, 0x30, 0x37, 0x30, 0x35, 0x30, 0x31, 0x30};
|
||||
json j = json::from_msgpack(data, sizeof(data) / sizeof(data[0]));
|
||||
CHECK_NOTHROW(
|
||||
j.dump(4, // Indent
|
||||
' ', // Indent char
|
||||
false, // Ensure ascii
|
||||
json::error_handler_t::strict // Error
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
SECTION("PR #2181 - regression bug with lvalue")
|
||||
{
|
||||
// see https://github.com/nlohmann/json/pull/2181#issuecomment-653326060
|
||||
json j{{"x", "test"}};
|
||||
std::string defval = "default value";
|
||||
auto val = j.value("x", defval);
|
||||
auto val2 = j.value("y", defval);
|
||||
}
|
||||
|
||||
SECTION("issue #2293 - eof doesnt cause parsing to stop")
|
||||
{
|
||||
std::vector<uint8_t> data =
|
||||
{
|
||||
0x7B, 0x6F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x4F, 0x42
|
||||
};
|
||||
json result = json::from_cbor(data, true, false);
|
||||
CHECK(result.is_discarded());
|
||||
}
|
||||
|
||||
SECTION("issue #2315 - json.update and vector<pair>does not work with ordered_json")
|
||||
{
|
||||
nlohmann::ordered_json jsonAnimals = {{"animal", "dog"}};
|
||||
nlohmann::ordered_json jsonCat = {{"animal", "cat"}};
|
||||
jsonAnimals.update(jsonCat);
|
||||
CHECK(jsonAnimals["animal"] == "cat");
|
||||
|
||||
auto jsonAnimals_parsed = nlohmann::ordered_json::parse(jsonAnimals.dump());
|
||||
CHECK(jsonAnimals == jsonAnimals_parsed);
|
||||
|
||||
std::vector<std::pair<std::string, int64_t>> intData = {std::make_pair("aaaa", 11),
|
||||
std::make_pair("bbb", 222)
|
||||
};
|
||||
nlohmann::ordered_json jsonObj;
|
||||
for (const auto& data : intData)
|
||||
{
|
||||
jsonObj[data.first] = data.second;
|
||||
}
|
||||
CHECK(jsonObj["aaaa"] == 11);
|
||||
CHECK(jsonObj["bbb"] == 222);
|
||||
}
|
||||
|
||||
SECTION("issue #2330 - ignore_comment=true fails on multiple consecutive lines starting with comments")
|
||||
{
|
||||
std::string ss = "//\n//\n{\n}\n";
|
||||
json j = json::parse(ss, nullptr, true, true);
|
||||
CHECK(j.dump() == "{}");
|
||||
}
|
||||
|
||||
#ifdef JSON_HAS_CPP_20
|
||||
SECTION("issue #2546 - parsing containers of std::byte")
|
||||
{
|
||||
const char DATA[] = R"("Hello, world!")";
|
||||
const auto s = std::as_bytes(std::span(DATA));
|
||||
json j = json::parse(s);
|
||||
CHECK(j.dump() == "\"Hello, world!\"");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
322
vendor/json/test/src/unit-serialization.cpp
vendored
Normal file
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
TEST_CASE("serialization")
|
||||
{
|
||||
SECTION("operator<<")
|
||||
{
|
||||
SECTION("no given width")
|
||||
{
|
||||
std::stringstream ss;
|
||||
json j = {"foo", 1, 2, 3, false, {{"one", 1}}};
|
||||
ss << j;
|
||||
CHECK(ss.str() == "[\"foo\",1,2,3,false,{\"one\":1}]");
|
||||
}
|
||||
|
||||
SECTION("given width")
|
||||
{
|
||||
std::stringstream ss;
|
||||
json j = {"foo", 1, 2, 3, false, {{"one", 1}}};
|
||||
ss << std::setw(4) << j;
|
||||
CHECK(ss.str() ==
|
||||
"[\n \"foo\",\n 1,\n 2,\n 3,\n false,\n {\n \"one\": 1\n }\n]");
|
||||
}
|
||||
|
||||
SECTION("given fill")
|
||||
{
|
||||
std::stringstream ss;
|
||||
json j = {"foo", 1, 2, 3, false, {{"one", 1}}};
|
||||
ss << std::setw(1) << std::setfill('\t') << j;
|
||||
CHECK(ss.str() ==
|
||||
"[\n\t\"foo\",\n\t1,\n\t2,\n\t3,\n\tfalse,\n\t{\n\t\t\"one\": 1\n\t}\n]");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("operator>>")
|
||||
{
|
||||
SECTION("no given width")
|
||||
{
|
||||
std::stringstream ss;
|
||||
json j = {"foo", 1, 2, 3, false, {{"one", 1}}};
|
||||
j >> ss;
|
||||
CHECK(ss.str() == "[\"foo\",1,2,3,false,{\"one\":1}]");
|
||||
}
|
||||
|
||||
SECTION("given width")
|
||||
{
|
||||
std::stringstream ss;
|
||||
json j = {"foo", 1, 2, 3, false, {{"one", 1}}};
|
||||
ss.width(4);
|
||||
j >> ss;
|
||||
CHECK(ss.str() ==
|
||||
"[\n \"foo\",\n 1,\n 2,\n 3,\n false,\n {\n \"one\": 1\n }\n]");
|
||||
}
|
||||
|
||||
SECTION("given fill")
|
||||
{
|
||||
std::stringstream ss;
|
||||
json j = {"foo", 1, 2, 3, false, {{"one", 1}}};
|
||||
ss.width(1);
|
||||
ss.fill('\t');
|
||||
j >> ss;
|
||||
CHECK(ss.str() ==
|
||||
"[\n\t\"foo\",\n\t1,\n\t2,\n\t3,\n\tfalse,\n\t{\n\t\t\"one\": 1\n\t}\n]");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("dump")
|
||||
{
|
||||
SECTION("invalid character")
|
||||
{
|
||||
json j = "ä\xA9ü";
|
||||
|
||||
CHECK_THROWS_AS(j.dump(), json::type_error&);
|
||||
CHECK_THROWS_WITH(j.dump(), "[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9");
|
||||
CHECK_THROWS_AS(j.dump(1, ' ', false, json::error_handler_t::strict), json::type_error&);
|
||||
CHECK_THROWS_WITH(j.dump(1, ' ', false, json::error_handler_t::strict), "[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9");
|
||||
CHECK(j.dump(-1, ' ', false, json::error_handler_t::ignore) == "\"äü\"");
|
||||
CHECK(j.dump(-1, ' ', false, json::error_handler_t::replace) == "\"ä\xEF\xBF\xBDü\"");
|
||||
CHECK(j.dump(-1, ' ', true, json::error_handler_t::replace) == "\"\\u00e4\\ufffd\\u00fc\"");
|
||||
}
|
||||
|
||||
SECTION("ending with incomplete character")
|
||||
{
|
||||
json j = "123\xC2";
|
||||
|
||||
CHECK_THROWS_AS(j.dump(), json::type_error&);
|
||||
CHECK_THROWS_WITH(j.dump(), "[json.exception.type_error.316] incomplete UTF-8 string; last byte: 0xC2");
|
||||
CHECK_THROWS_AS(j.dump(1, ' ', false, json::error_handler_t::strict), json::type_error&);
|
||||
CHECK(j.dump(-1, ' ', false, json::error_handler_t::ignore) == "\"123\"");
|
||||
CHECK(j.dump(-1, ' ', false, json::error_handler_t::replace) == "\"123\xEF\xBF\xBD\"");
|
||||
CHECK(j.dump(-1, ' ', true, json::error_handler_t::replace) == "\"123\\ufffd\"");
|
||||
}
|
||||
|
||||
SECTION("unexpected character")
|
||||
{
|
||||
json j = "123\xF1\xB0\x34\x35\x36";
|
||||
|
||||
CHECK_THROWS_AS(j.dump(), json::type_error&);
|
||||
CHECK_THROWS_WITH(j.dump(), "[json.exception.type_error.316] invalid UTF-8 byte at index 5: 0x34");
|
||||
CHECK_THROWS_AS(j.dump(1, ' ', false, json::error_handler_t::strict), json::type_error&);
|
||||
CHECK(j.dump(-1, ' ', false, json::error_handler_t::ignore) == "\"123456\"");
|
||||
CHECK(j.dump(-1, ' ', false, json::error_handler_t::replace) == "\"123\xEF\xBF\xBD\x34\x35\x36\"");
|
||||
CHECK(j.dump(-1, ' ', true, json::error_handler_t::replace) == "\"123\\ufffd456\"");
|
||||
}
|
||||
|
||||
SECTION("U+FFFD Substitution of Maximal Subparts")
|
||||
{
|
||||
// Some tests (mostly) from
|
||||
// https://www.unicode.org/versions/Unicode11.0.0/ch03.pdf
|
||||
// Section 3.9 -- U+FFFD Substitution of Maximal Subparts
|
||||
|
||||
auto test = [&](std::string const & input, std::string const & expected)
|
||||
{
|
||||
json j = input;
|
||||
CHECK(j.dump(-1, ' ', true, json::error_handler_t::replace) == "\"" + expected + "\"");
|
||||
};
|
||||
|
||||
test("\xC2", "\\ufffd");
|
||||
test("\xC2\x41\x42", "\\ufffd" "\x41" "\x42");
|
||||
test("\xC2\xF4", "\\ufffd" "\\ufffd");
|
||||
|
||||
test("\xF0\x80\x80\x41", "\\ufffd" "\\ufffd" "\\ufffd" "\x41");
|
||||
test("\xF1\x80\x80\x41", "\\ufffd" "\x41");
|
||||
test("\xF2\x80\x80\x41", "\\ufffd" "\x41");
|
||||
test("\xF3\x80\x80\x41", "\\ufffd" "\x41");
|
||||
test("\xF4\x80\x80\x41", "\\ufffd" "\x41");
|
||||
test("\xF5\x80\x80\x41", "\\ufffd" "\\ufffd" "\\ufffd" "\x41");
|
||||
|
||||
test("\xF0\x90\x80\x41", "\\ufffd" "\x41");
|
||||
test("\xF1\x90\x80\x41", "\\ufffd" "\x41");
|
||||
test("\xF2\x90\x80\x41", "\\ufffd" "\x41");
|
||||
test("\xF3\x90\x80\x41", "\\ufffd" "\x41");
|
||||
test("\xF4\x90\x80\x41", "\\ufffd" "\\ufffd" "\\ufffd" "\x41");
|
||||
test("\xF5\x90\x80\x41", "\\ufffd" "\\ufffd" "\\ufffd" "\x41");
|
||||
|
||||
test("\xC0\xAF\xE0\x80\xBF\xF0\x81\x82\x41", "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\x41");
|
||||
test("\xED\xA0\x80\xED\xBF\xBF\xED\xAF\x41", "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\x41");
|
||||
test("\xF4\x91\x92\x93\xFF\x41\x80\xBF\x42", "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\x41" "\\ufffd""\\ufffd" "\x42");
|
||||
test("\xE1\x80\xE2\xF0\x91\x92\xF1\xBF\x41", "\\ufffd" "\\ufffd" "\\ufffd" "\\ufffd" "\x41");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("to_string")
|
||||
{
|
||||
auto test = [&](std::string const & input, std::string const & expected)
|
||||
{
|
||||
using std::to_string;
|
||||
json j = input;
|
||||
CHECK(to_string(j) == "\"" + expected + "\"");
|
||||
};
|
||||
|
||||
test("{\"x\":5,\"y\":6}", "{\\\"x\\\":5,\\\"y\\\":6}");
|
||||
test("{\"x\":[10,null,null,null]}", "{\\\"x\\\":[10,null,null,null]}");
|
||||
test("test", "test");
|
||||
test("[3,\"false\",false]", "[3,\\\"false\\\",false]");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE_TEMPLATE("serialization for extreme integer values", T, int32_t, uint32_t, int64_t, uint64_t)
|
||||
{
|
||||
SECTION("minimum")
|
||||
{
|
||||
constexpr auto minimum = (std::numeric_limits<T>::min)();
|
||||
json j = minimum;
|
||||
CHECK(j.dump() == std::to_string(minimum));
|
||||
}
|
||||
|
||||
SECTION("maximum")
|
||||
{
|
||||
constexpr auto maximum = (std::numeric_limits<T>::max)();
|
||||
json j = maximum;
|
||||
CHECK(j.dump() == std::to_string(maximum));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("dump with binary values")
|
||||
{
|
||||
auto binary = json::binary({1, 2, 3, 4});
|
||||
auto binary_empty = json::binary({});
|
||||
auto binary_with_subtype = json::binary({1, 2, 3, 4}, 128);
|
||||
auto binary_empty_with_subtype = json::binary({}, 128);
|
||||
|
||||
json object = {{"key", binary}};
|
||||
json object_empty = {{"key", binary_empty}};
|
||||
json object_with_subtype = {{"key", binary_with_subtype}};
|
||||
json object_empty_with_subtype = {{"key", binary_empty_with_subtype}};
|
||||
|
||||
json array = {"value", 1, binary};
|
||||
json array_empty = {"value", 1, binary_empty};
|
||||
json array_with_subtype = {"value", 1, binary_with_subtype};
|
||||
json array_empty_with_subtype = {"value", 1, binary_empty_with_subtype};
|
||||
|
||||
SECTION("normal")
|
||||
{
|
||||
CHECK(binary.dump() == "{\"bytes\":[1,2,3,4],\"subtype\":null}");
|
||||
CHECK(binary_empty.dump() == "{\"bytes\":[],\"subtype\":null}");
|
||||
CHECK(binary_with_subtype.dump() == "{\"bytes\":[1,2,3,4],\"subtype\":128}");
|
||||
CHECK(binary_empty_with_subtype.dump() == "{\"bytes\":[],\"subtype\":128}");
|
||||
|
||||
CHECK(object.dump() == "{\"key\":{\"bytes\":[1,2,3,4],\"subtype\":null}}");
|
||||
CHECK(object_empty.dump() == "{\"key\":{\"bytes\":[],\"subtype\":null}}");
|
||||
CHECK(object_with_subtype.dump() == "{\"key\":{\"bytes\":[1,2,3,4],\"subtype\":128}}");
|
||||
CHECK(object_empty_with_subtype.dump() == "{\"key\":{\"bytes\":[],\"subtype\":128}}");
|
||||
|
||||
CHECK(array.dump() == "[\"value\",1,{\"bytes\":[1,2,3,4],\"subtype\":null}]");
|
||||
CHECK(array_empty.dump() == "[\"value\",1,{\"bytes\":[],\"subtype\":null}]");
|
||||
CHECK(array_with_subtype.dump() == "[\"value\",1,{\"bytes\":[1,2,3,4],\"subtype\":128}]");
|
||||
CHECK(array_empty_with_subtype.dump() == "[\"value\",1,{\"bytes\":[],\"subtype\":128}]");
|
||||
}
|
||||
|
||||
SECTION("pretty-printed")
|
||||
{
|
||||
CHECK(binary.dump(4) == "{\n"
|
||||
" \"bytes\": [1, 2, 3, 4],\n"
|
||||
" \"subtype\": null\n"
|
||||
"}");
|
||||
CHECK(binary_empty.dump(4) == "{\n"
|
||||
" \"bytes\": [],\n"
|
||||
" \"subtype\": null\n"
|
||||
"}");
|
||||
CHECK(binary_with_subtype.dump(4) == "{\n"
|
||||
" \"bytes\": [1, 2, 3, 4],\n"
|
||||
" \"subtype\": 128\n"
|
||||
"}");
|
||||
CHECK(binary_empty_with_subtype.dump(4) == "{\n"
|
||||
" \"bytes\": [],\n"
|
||||
" \"subtype\": 128\n"
|
||||
"}");
|
||||
|
||||
CHECK(object.dump(4) == "{\n"
|
||||
" \"key\": {\n"
|
||||
" \"bytes\": [1, 2, 3, 4],\n"
|
||||
" \"subtype\": null\n"
|
||||
" }\n"
|
||||
"}");
|
||||
CHECK(object_empty.dump(4) == "{\n"
|
||||
" \"key\": {\n"
|
||||
" \"bytes\": [],\n"
|
||||
" \"subtype\": null\n"
|
||||
" }\n"
|
||||
"}");
|
||||
CHECK(object_with_subtype.dump(4) == "{\n"
|
||||
" \"key\": {\n"
|
||||
" \"bytes\": [1, 2, 3, 4],\n"
|
||||
" \"subtype\": 128\n"
|
||||
" }\n"
|
||||
"}");
|
||||
CHECK(object_empty_with_subtype.dump(4) == "{\n"
|
||||
" \"key\": {\n"
|
||||
" \"bytes\": [],\n"
|
||||
" \"subtype\": 128\n"
|
||||
" }\n"
|
||||
"}");
|
||||
|
||||
CHECK(array.dump(4) == "[\n"
|
||||
" \"value\",\n"
|
||||
" 1,\n"
|
||||
" {\n"
|
||||
" \"bytes\": [1, 2, 3, 4],\n"
|
||||
" \"subtype\": null\n"
|
||||
" }\n"
|
||||
"]");
|
||||
CHECK(array_empty.dump(4) == "[\n"
|
||||
" \"value\",\n"
|
||||
" 1,\n"
|
||||
" {\n"
|
||||
" \"bytes\": [],\n"
|
||||
" \"subtype\": null\n"
|
||||
" }\n"
|
||||
"]");
|
||||
CHECK(array_with_subtype.dump(4) == "[\n"
|
||||
" \"value\",\n"
|
||||
" 1,\n"
|
||||
" {\n"
|
||||
" \"bytes\": [1, 2, 3, 4],\n"
|
||||
" \"subtype\": 128\n"
|
||||
" }\n"
|
||||
"]");
|
||||
CHECK(array_empty_with_subtype.dump(4) == "[\n"
|
||||
" \"value\",\n"
|
||||
" 1,\n"
|
||||
" {\n"
|
||||
" \"bytes\": [],\n"
|
||||
" \"subtype\": 128\n"
|
||||
" }\n"
|
||||
"]");
|
||||
}
|
||||
}
|
||||
1416
vendor/json/test/src/unit-testsuites.cpp
vendored
Normal file
537
vendor/json/test/src/unit-to_chars.cpp
vendored
Normal file
@@ -0,0 +1,537 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
// XXX:
|
||||
// Only compile these tests if 'float' and 'double' are IEEE-754 single- and
|
||||
// double-precision numbers, resp.
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::detail::dtoa_impl::reinterpret_bits;
|
||||
|
||||
namespace
|
||||
{
|
||||
static float make_float(uint32_t sign_bit, uint32_t biased_exponent, uint32_t significand)
|
||||
{
|
||||
assert(sign_bit == 0 || sign_bit == 1);
|
||||
assert(biased_exponent <= 0xFF);
|
||||
assert(significand <= 0x007FFFFF);
|
||||
|
||||
uint32_t bits = 0;
|
||||
|
||||
bits |= sign_bit << 31;
|
||||
bits |= biased_exponent << 23;
|
||||
bits |= significand;
|
||||
|
||||
return reinterpret_bits<float>(bits);
|
||||
}
|
||||
|
||||
// ldexp -- convert f * 2^e to IEEE single precision
|
||||
static float make_float(uint64_t f, int e)
|
||||
{
|
||||
constexpr uint64_t kHiddenBit = 0x00800000;
|
||||
constexpr uint64_t kSignificandMask = 0x007FFFFF;
|
||||
constexpr int kPhysicalSignificandSize = 23; // Excludes the hidden bit.
|
||||
constexpr int kExponentBias = 0x7F + kPhysicalSignificandSize;
|
||||
constexpr int kDenormalExponent = 1 - kExponentBias;
|
||||
constexpr int kMaxExponent = 0xFF - kExponentBias;
|
||||
|
||||
while (f > kHiddenBit + kSignificandMask)
|
||||
{
|
||||
f >>= 1;
|
||||
e++;
|
||||
}
|
||||
if (e >= kMaxExponent)
|
||||
{
|
||||
return std::numeric_limits<float>::infinity();
|
||||
}
|
||||
if (e < kDenormalExponent)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
while (e > kDenormalExponent && (f & kHiddenBit) == 0)
|
||||
{
|
||||
f <<= 1;
|
||||
e--;
|
||||
}
|
||||
|
||||
uint64_t biased_exponent = (e == kDenormalExponent && (f & kHiddenBit) == 0)
|
||||
? 0
|
||||
: static_cast<uint64_t>(e + kExponentBias);
|
||||
|
||||
uint64_t bits = (f & kSignificandMask) | (biased_exponent << kPhysicalSignificandSize);
|
||||
return reinterpret_bits<float>(static_cast<uint32_t>(bits));
|
||||
}
|
||||
|
||||
static double make_double(uint64_t sign_bit, uint64_t biased_exponent, uint64_t significand)
|
||||
{
|
||||
assert(sign_bit == 0 || sign_bit == 1);
|
||||
assert(biased_exponent <= 0x7FF);
|
||||
assert(significand <= 0x000FFFFFFFFFFFFF);
|
||||
|
||||
uint64_t bits = 0;
|
||||
|
||||
bits |= sign_bit << 63;
|
||||
bits |= biased_exponent << 52;
|
||||
bits |= significand;
|
||||
|
||||
return reinterpret_bits<double>(bits);
|
||||
}
|
||||
|
||||
// ldexp -- convert f * 2^e to IEEE double precision
|
||||
static double make_double(uint64_t f, int e)
|
||||
{
|
||||
constexpr uint64_t kHiddenBit = 0x0010000000000000;
|
||||
constexpr uint64_t kSignificandMask = 0x000FFFFFFFFFFFFF;
|
||||
constexpr int kPhysicalSignificandSize = 52; // Excludes the hidden bit.
|
||||
constexpr int kExponentBias = 0x3FF + kPhysicalSignificandSize;
|
||||
constexpr int kDenormalExponent = 1 - kExponentBias;
|
||||
constexpr int kMaxExponent = 0x7FF - kExponentBias;
|
||||
|
||||
while (f > kHiddenBit + kSignificandMask)
|
||||
{
|
||||
f >>= 1;
|
||||
e++;
|
||||
}
|
||||
if (e >= kMaxExponent)
|
||||
{
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
if (e < kDenormalExponent)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
while (e > kDenormalExponent && (f & kHiddenBit) == 0)
|
||||
{
|
||||
f <<= 1;
|
||||
e--;
|
||||
}
|
||||
|
||||
uint64_t biased_exponent = (e == kDenormalExponent && (f & kHiddenBit) == 0)
|
||||
? 0
|
||||
: static_cast<uint64_t>(e + kExponentBias);
|
||||
|
||||
uint64_t bits = (f & kSignificandMask) | (biased_exponent << kPhysicalSignificandSize);
|
||||
return reinterpret_bits<double>(bits);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("digit gen")
|
||||
{
|
||||
SECTION("single precision")
|
||||
{
|
||||
auto check_float = [](float number, const std::string & digits, int expected_exponent)
|
||||
{
|
||||
CAPTURE(number)
|
||||
CAPTURE(digits)
|
||||
CAPTURE(expected_exponent)
|
||||
|
||||
char buf[32];
|
||||
int len = 0;
|
||||
int exponent = 0;
|
||||
nlohmann::detail::dtoa_impl::grisu2(buf, len, exponent, number);
|
||||
|
||||
CHECK(digits == std::string(buf, buf + len));
|
||||
CHECK(expected_exponent == exponent);
|
||||
};
|
||||
|
||||
check_float(make_float(0, 0, 0x00000001), "1", -45); // min denormal
|
||||
check_float(make_float(0, 0, 0x007FFFFF), "11754942", -45); // max denormal
|
||||
check_float(make_float(0, 1, 0x00000000), "11754944", -45); // min normal
|
||||
check_float(make_float(0, 1, 0x00000001), "11754945", -45);
|
||||
check_float(make_float(0, 1, 0x007FFFFF), "23509886", -45);
|
||||
check_float(make_float(0, 2, 0x00000000), "23509887", -45);
|
||||
check_float(make_float(0, 2, 0x00000001), "2350989", -44);
|
||||
check_float(make_float(0, 24, 0x00000000), "98607613", -39); // fail if no special case in normalized boundaries
|
||||
check_float(make_float(0, 30, 0x00000000), "63108872", -37); // fail if no special case in normalized boundaries
|
||||
check_float(make_float(0, 31, 0x00000000), "12621775", -36); // fail if no special case in normalized boundaries
|
||||
check_float(make_float(0, 57, 0x00000000), "84703295", -29); // fail if no special case in normalized boundaries
|
||||
check_float(make_float(0, 254, 0x007FFFFE), "34028233", 31);
|
||||
check_float(make_float(0, 254, 0x007FFFFF), "34028235", 31); // max normal
|
||||
|
||||
// V. Paxson and W. Kahan, "A Program for Testing IEEE Binary-Decimal Conversion", manuscript, May 1991,
|
||||
// ftp://ftp.ee.lbl.gov/testbase-report.ps.Z (report)
|
||||
// ftp://ftp.ee.lbl.gov/testbase.tar.Z (program)
|
||||
|
||||
// Table 16: Stress Inputs for Converting 24-bit Binary to Decimal, < 1/2 ULP
|
||||
check_float(make_float(12676506, -102), "25", -25);
|
||||
check_float(make_float(12676506, -103), "125", -26);
|
||||
check_float(make_float(15445013, 86), "1195", 30);
|
||||
check_float(make_float(13734123, -138), "39415", -39);
|
||||
check_float(make_float(12428269, -130), "913085", -38);
|
||||
check_float(make_float(15334037, -146), "1719005", -43);
|
||||
check_float(make_float(11518287, -41), "52379105", -13);
|
||||
check_float(make_float(12584953, -145), "2821644", -43);
|
||||
check_float(make_float(15961084, -125), "37524328", -38);
|
||||
check_float(make_float(14915817, -146), "16721209", -44);
|
||||
check_float(make_float(10845484, -102), "21388946", -31);
|
||||
check_float(make_float(16431059, -61), "7125836", -18);
|
||||
|
||||
// Table 17: Stress Inputs for Converting 24-bit Binary to Decimal, > 1/2 ULP
|
||||
check_float(make_float(16093626, 69), "95", 26);
|
||||
check_float(make_float( 9983778, 25), "335", 12);
|
||||
check_float(make_float(12745034, 104), "2585", 35);
|
||||
check_float(make_float(12706553, 72), "60005", 24);
|
||||
check_float(make_float(11005028, 45), "387205", 15);
|
||||
check_float(make_float(15059547, 71), "3555835", 22);
|
||||
check_float(make_float(16015691, -99), "25268305", -30);
|
||||
check_float(make_float( 8667859, 56), "6245851", 17);
|
||||
check_float(make_float(14855922, -82), "30721327", -25);
|
||||
check_float(make_float(14855922, -83), "15360663", -25);
|
||||
check_float(make_float(10144164, -110), "781478", -32);
|
||||
check_float(make_float(13248074, 95), "52481028", 28);
|
||||
}
|
||||
|
||||
SECTION("double precision")
|
||||
{
|
||||
auto check_double = [](double number, const std::string & digits, int expected_exponent)
|
||||
{
|
||||
CAPTURE(number)
|
||||
CAPTURE(digits)
|
||||
CAPTURE(expected_exponent)
|
||||
|
||||
char buf[32];
|
||||
int len = 0;
|
||||
int exponent = 0;
|
||||
nlohmann::detail::dtoa_impl::grisu2(buf, len, exponent, number);
|
||||
|
||||
CHECK(digits == std::string(buf, buf + len));
|
||||
CHECK(expected_exponent == exponent);
|
||||
};
|
||||
|
||||
check_double(make_double(0, 0, 0x0000000000000001), "5", -324); // min denormal
|
||||
check_double(make_double(0, 0, 0x000FFFFFFFFFFFFF), "2225073858507201", -323); // max denormal
|
||||
check_double(make_double(0, 1, 0x0000000000000000), "22250738585072014", -324); // min normal
|
||||
check_double(make_double(0, 1, 0x0000000000000001), "2225073858507202", -323);
|
||||
check_double(make_double(0, 1, 0x000FFFFFFFFFFFFF), "44501477170144023", -324);
|
||||
check_double(make_double(0, 2, 0x0000000000000000), "4450147717014403", -323);
|
||||
check_double(make_double(0, 2, 0x0000000000000001), "4450147717014404", -323);
|
||||
check_double(make_double(0, 4, 0x0000000000000000), "17800590868057611", -323); // fail if no special case in normalized boundaries
|
||||
check_double(make_double(0, 5, 0x0000000000000000), "35601181736115222", -323); // fail if no special case in normalized boundaries
|
||||
check_double(make_double(0, 6, 0x0000000000000000), "7120236347223045", -322); // fail if no special case in normalized boundaries
|
||||
check_double(make_double(0, 10, 0x0000000000000000), "11392378155556871", -321); // fail if no special case in normalized boundaries
|
||||
check_double(make_double(0, 2046, 0x000FFFFFFFFFFFFE), "17976931348623155", 292);
|
||||
check_double(make_double(0, 2046, 0x000FFFFFFFFFFFFF), "17976931348623157", 292); // max normal
|
||||
|
||||
// Test different paths in DigitGen
|
||||
check_double( 10000, "1", 4);
|
||||
check_double( 1200000, "12", 5);
|
||||
check_double(4.9406564584124654e-324, "5", -324); // exit integral loop
|
||||
check_double(2.2250738585072009e-308, "2225073858507201", -323); // exit fractional loop
|
||||
check_double( 1.82877982605164e-99, "182877982605164", -113);
|
||||
check_double( 1.1505466208671903e-09, "11505466208671903", -25);
|
||||
check_double( 5.5645893133766722e+20, "5564589313376672", 5);
|
||||
check_double( 53.034830388866226, "53034830388866226", -15);
|
||||
check_double( 0.0021066531670178605, "21066531670178605", -19);
|
||||
|
||||
// V. Paxson and W. Kahan, "A Program for Testing IEEE Binary-Decimal Conversion", manuscript, May 1991,
|
||||
// ftp://ftp.ee.lbl.gov/testbase-report.ps.Z (report)
|
||||
// ftp://ftp.ee.lbl.gov/testbase.tar.Z (program)
|
||||
|
||||
// Table 3: Stress Inputs for Converting 53-bit Binary to Decimal, < 1/2 ULP
|
||||
check_double(make_double(8511030020275656, -342) /* 9.5e-088 */, "95", -89);
|
||||
check_double(make_double(5201988407066741, -824) /* 4.65e-233 */, "465", -235);
|
||||
check_double(make_double(6406892948269899, +237) /* 1.415e+087 */, "1415", 84);
|
||||
check_double(make_double(8431154198732492, +72) /* 3.9815e+037 */, "39815", 33);
|
||||
check_double(make_double(6475049196144587, +99) /* 4.10405e+045 */, "410405", 40);
|
||||
check_double(make_double(8274307542972842, +726) /* 2.920845e+234 */, "2920845", 228);
|
||||
check_double(make_double(5381065484265332, -456) /* 2.8919465e-122 */, "28919465", -129);
|
||||
check_double(make_double(6761728585499734, -1057) /* 4.37877185e-303 */, "437877185", -311);
|
||||
check_double(make_double(7976538478610756, +376) /* 1.227701635e+129 */, "1227701635", 120);
|
||||
check_double(make_double(5982403858958067, +377) /* 1.8415524525e+129 */, "18415524525", 119);
|
||||
check_double(make_double(5536995190630837, +93) /* 5.48357443505e+043 */, "548357443505", 32);
|
||||
check_double(make_double(7225450889282194, +710) /* 3.891901811465e+229 */, "3891901811465", 217);
|
||||
check_double(make_double(7225450889282194, +709) /* 1.9459509057325e+229 */, "19459509057325", 216);
|
||||
check_double(make_double(8703372741147379, +117) /* 1.44609583816055e+051 */, "144609583816055", 37);
|
||||
check_double(make_double(8944262675275217, -1001) /* 4.173677474585315e-286 */, "4173677474585315", -301);
|
||||
check_double(make_double(7459803696087692, -707) /* 1.1079507728788885e-197 */, "11079507728788885", -213);
|
||||
check_double(make_double(6080469016670379, -381) /* 1.234550136632744e-099 */, "1234550136632744", -114);
|
||||
check_double(make_double(8385515147034757, +721) /* 9.2503171196036502e+232 */, "925031711960365", 218);
|
||||
check_double(make_double(7514216811389786, -828) /* 4.1980471502848898e-234 */, "419804715028489", -248);
|
||||
check_double(make_double(8397297803260511, -345) /* 1.1716315319786511e-088 */, "11716315319786511", -104);
|
||||
check_double(make_double(6733459239310543, +202) /* 4.3281007284461249e+076 */, "4328100728446125", 61);
|
||||
check_double(make_double(8091450587292794, -473) /* 3.3177101181600311e-127 */, "3317710118160031", -142);
|
||||
|
||||
// Table 4: Stress Inputs for Converting 53-bit Binary to Decimal, > 1/2 ULP
|
||||
check_double(make_double(6567258882077402, +952) /* 2.5e+302 */, "25", 301);
|
||||
check_double(make_double(6712731423444934, +535) /* 7.55e+176 */, "755", 174);
|
||||
check_double(make_double(6712731423444934, +534) /* 3.775e+176 */, "3775", 173);
|
||||
check_double(make_double(5298405411573037, -957) /* 4.3495e-273 */, "43495", -277);
|
||||
check_double(make_double(5137311167659507, -144) /* 2.30365e-028 */, "230365", -33);
|
||||
check_double(make_double(6722280709661868, +363) /* 1.263005e+125 */, "1263005", 119);
|
||||
check_double(make_double(5344436398034927, -169) /* 7.1422105e-036 */, "71422105", -43);
|
||||
check_double(make_double(8369123604277281, -853) /* 1.39345735e-241 */, "139345735", -249);
|
||||
check_double(make_double(8995822108487663, -780) /* 1.414634485e-219 */, "1414634485", -228);
|
||||
check_double(make_double(8942832835564782, -383) /* 4.5392779195e-100 */, "45392779195", -110);
|
||||
check_double(make_double(8942832835564782, -384) /* 2.26963895975e-100 */, "226963895975", -111);
|
||||
check_double(make_double(8942832835564782, -385) /* 1.134819479875e-100 */, "1134819479875", -112);
|
||||
check_double(make_double(6965949469487146, -249) /* 7.7003665618895e-060 */, "77003665618895", -73);
|
||||
check_double(make_double(6965949469487146, -250) /* 3.85018328094475e-060 */, "385018328094475", -74);
|
||||
check_double(make_double(6965949469487146, -251) /* 1.925091640472375e-060 */, "1925091640472375", -75);
|
||||
check_double(make_double(7487252720986826, +548) /* 6.8985865317742005e+180 */, "68985865317742005", 164);
|
||||
check_double(make_double(5592117679628511, +164) /* 1.3076622631878654e+065 */, "13076622631878654", 49);
|
||||
check_double(make_double(8887055249355788, +665) /* 1.3605202075612124e+216 */, "13605202075612124", 200);
|
||||
check_double(make_double(6994187472632449, +690) /* 3.5928102174759597e+223 */, "35928102174759597", 207);
|
||||
check_double(make_double(8797576579012143, +588) /* 8.9125197712484552e+192 */, "8912519771248455", 177);
|
||||
check_double(make_double(7363326733505337, +272) /* 5.5876975736230114e+097 */, "55876975736230114", 81);
|
||||
check_double(make_double(8549497411294502, -448) /* 1.1762578307285404e-119 */, "11762578307285404", -135);
|
||||
|
||||
// Table 20: Stress Inputs for Converting 56-bit Binary to Decimal, < 1/2 ULP
|
||||
check_double(make_double(50883641005312716, -172) /* 8.4999999999999993e-036 */, "8499999999999999", -51);
|
||||
check_double(make_double(38162730753984537, -170) /* 2.5499999999999999e-035 */, "255", -37);
|
||||
check_double(make_double(50832789069151999, -101) /* 2.0049999999999997e-014 */, "20049999999999997", -30);
|
||||
check_double(make_double(51822367833714164, -109) /* 7.9844999999999994e-017 */, "7984499999999999", -32);
|
||||
check_double(make_double(66840152193508133, -172) /* 1.1165499999999999e-035 */, "11165499999999999", -51);
|
||||
check_double(make_double(55111239245584393, -138) /* 1.581615e-025 */, "1581615", -31);
|
||||
check_double(make_double(71704866733321482, -112) /* 1.3809855e-017 */, "13809855", -24);
|
||||
check_double(make_double(67160949328233173, -142) /* 1.2046404499999999e-026 */, "12046404499999999", -42);
|
||||
check_double(make_double(53237141308040189, -152) /* 9.3251405449999991e-030 */, "9325140544999999", -45);
|
||||
check_double(make_double(62785329394975786, -112) /* 1.2092014595e-017 */, "12092014595", -27);
|
||||
check_double(make_double(48367680154689523, -77) /* 3.2007045838499998e-007 */, "320070458385", -18);
|
||||
check_double(make_double(42552223180606797, -102) /* 8.391946324354999e-015 */, "8391946324354999", -30);
|
||||
check_double(make_double(63626356173011241, -112) /* 1.2253990460585e-017 */, "12253990460585", -30);
|
||||
check_double(make_double(43566388595783643, -99) /* 6.8735641489760495e-014 */, "687356414897605", -28);
|
||||
check_double(make_double(54512669636675272, -159) /* 7.459816430480385e-032 */, "7459816430480385", -47);
|
||||
check_double(make_double(52306490527514614, -167) /* 2.7960588398142552e-034 */, "2796058839814255", -49);
|
||||
check_double(make_double(52306490527514614, -168) /* 1.3980294199071276e-034 */, "13980294199071276", -50);
|
||||
check_double(make_double(41024721590449423, -89) /* 6.6279012373057359e-011 */, "6627901237305736", -26);
|
||||
check_double(make_double(37664020415894738, -132) /* 6.9177880043968072e-024 */, "6917788004396807", -39);
|
||||
check_double(make_double(37549883692866294, -93) /* 3.7915693108349708e-012 */, "3791569310834971", -27);
|
||||
check_double(make_double(69124110374399839, -104) /* 3.4080817676591365e-015 */, "34080817676591365", -31);
|
||||
check_double(make_double(69124110374399839, -105) /* 1.7040408838295683e-015 */, "17040408838295683", -31);
|
||||
|
||||
// Table 21: Stress Inputs for Converting 56-bit Binary to Decimal, > 1/2 ULP
|
||||
check_double(make_double(49517601571415211, -94) /* 2.4999999999999998e-012 */, "25", -13);
|
||||
check_double(make_double(49517601571415211, -95) /* 1.2499999999999999e-012 */, "125", -14);
|
||||
check_double(make_double(54390733528642804, -133) /* 4.9949999999999996e-024 */, "49949999999999996", -40); // shortest: 4995e-27
|
||||
check_double(make_double(71805402319113924, -157) /* 3.9304999999999998e-031 */, "39304999999999998", -47); // shortest: 39305e-35
|
||||
check_double(make_double(40435277969631694, -179) /* 5.2770499999999992e-038 */, "5277049999999999", -53);
|
||||
check_double(make_double(57241991568619049, -165) /* 1.223955e-033 */, "1223955", -39);
|
||||
check_double(make_double(65224162876242886, +58) /* 1.8799584999999998e+034 */, "18799584999999998", 18);
|
||||
check_double(make_double(70173376848895368, -138) /* 2.01387715e-025 */, "201387715", -33);
|
||||
check_double(make_double(37072848117383207, -99) /* 5.8490641049999989e-014 */, "5849064104999999", -29);
|
||||
check_double(make_double(56845051585389697, -176) /* 5.9349003054999999e-037 */, "59349003055", -47);
|
||||
check_double(make_double(54791673366936431, -145) /* 1.2284718039499998e-027 */, "12284718039499998", -43);
|
||||
check_double(make_double(66800318669106231, -169) /* 8.9270767180849991e-035 */, "8927076718084999", -50);
|
||||
check_double(make_double(66800318669106231, -170) /* 4.4635383590424995e-035 */, "44635383590424995", -51);
|
||||
check_double(make_double(66574323440112438, -119) /* 1.0016990862549499e-019 */, "10016990862549499", -35);
|
||||
check_double(make_double(65645179969330963, -173) /* 5.4829412628024647e-036 */, "5482941262802465", -51);
|
||||
check_double(make_double(61847254334681076, -109) /* 9.5290783281036439e-017 */, "9529078328103644", -32);
|
||||
check_double(make_double(39990712921393606, -145) /* 8.9662279366405553e-028 */, "8966227936640555", -43);
|
||||
check_double(make_double(59292318184400283, -149) /* 8.3086234418058538e-029 */, "8308623441805854", -44);
|
||||
check_double(make_double(69116558615326153, -143) /* 6.1985873566126555e-027 */, "61985873566126555", -43);
|
||||
check_double(make_double(69116558615326153, -144) /* 3.0992936783063277e-027 */, "30992936783063277", -43);
|
||||
check_double(make_double(39462549494468513, -152) /* 6.9123512506176015e-030 */, "6912351250617602", -45);
|
||||
check_double(make_double(39462549494468513, -153) /* 3.4561756253088008e-030 */, "3456175625308801", -45);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("formatting")
|
||||
{
|
||||
SECTION("single precision")
|
||||
{
|
||||
auto check_float = [](float number, const std::string & expected)
|
||||
{
|
||||
std::array<char, 33> buf{};
|
||||
char* end = nlohmann::detail::to_chars(buf.data(), buf.data() + 32, number);
|
||||
std::string actual(buf.data(), end);
|
||||
|
||||
CHECK(actual == expected);
|
||||
};
|
||||
// %.9g
|
||||
check_float( -1.2345e-22f, "-1.2345e-22" ); // -1.23450004e-22
|
||||
check_float( -1.2345e-21f, "-1.2345e-21" ); // -1.23450002e-21
|
||||
check_float( -1.2345e-20f, "-1.2345e-20" ); // -1.23450002e-20
|
||||
check_float( -1.2345e-19f, "-1.2345e-19" ); // -1.23449999e-19
|
||||
check_float( -1.2345e-18f, "-1.2345e-18" ); // -1.23449996e-18
|
||||
check_float( -1.2345e-17f, "-1.2345e-17" ); // -1.23449998e-17
|
||||
check_float( -1.2345e-16f, "-1.2345e-16" ); // -1.23449996e-16
|
||||
check_float( -1.2345e-15f, "-1.2345e-15" ); // -1.23450002e-15
|
||||
check_float( -1.2345e-14f, "-1.2345e-14" ); // -1.23450004e-14
|
||||
check_float( -1.2345e-13f, "-1.2345e-13" ); // -1.23449997e-13
|
||||
check_float( -1.2345e-12f, "-1.2345e-12" ); // -1.23450002e-12
|
||||
check_float( -1.2345e-11f, "-1.2345e-11" ); // -1.2345e-11
|
||||
check_float( -1.2345e-10f, "-1.2345e-10" ); // -1.2345e-10
|
||||
check_float( -1.2345e-9f, "-1.2345e-09" ); // -1.23449995e-09
|
||||
check_float( -1.2345e-8f, "-1.2345e-08" ); // -1.23449997e-08
|
||||
check_float( -1.2345e-7f, "-1.2345e-07" ); // -1.23449993e-07
|
||||
check_float( -1.2345e-6f, "-1.2345e-06" ); // -1.23450002e-06
|
||||
check_float( -1.2345e-5f, "-1.2345e-05" ); // -1.2345e-05
|
||||
check_float( -1.2345e-4f, "-0.00012345" ); // -0.000123449994
|
||||
check_float( -1.2345e-3f, "-0.0012345" ); // -0.00123449997
|
||||
check_float( -1.2345e-2f, "-0.012345" ); // -0.0123450002
|
||||
check_float( -1.2345e-1f, "-0.12345" ); // -0.123450004
|
||||
check_float( -0.0f, "-0.0" ); // -0
|
||||
check_float( 0.0f, "0.0" ); // 0
|
||||
check_float( 1.2345e+0f, "1.2345" ); // 1.23450005
|
||||
check_float( 1.2345e+1f, "12.345" ); // 12.3450003
|
||||
check_float( 1.2345e+2f, "123.45" ); // 123.449997
|
||||
check_float( 1.2345e+3f, "1234.5" ); // 1234.5
|
||||
check_float( 1.2345e+4f, "12345.0" ); // 12345
|
||||
check_float( 1.2345e+5f, "123450.0" ); // 123450
|
||||
check_float( 1.2345e+6f, "1.2345e+06" ); // 1234500
|
||||
check_float( 1.2345e+7f, "1.2345e+07" ); // 12345000
|
||||
check_float( 1.2345e+8f, "1.2345e+08" ); // 123450000
|
||||
check_float( 1.2345e+9f, "1.2345e+09" ); // 1.23449997e+09
|
||||
check_float( 1.2345e+10f, "1.2345e+10" ); // 1.23449999e+10
|
||||
check_float( 1.2345e+11f, "1.2345e+11" ); // 1.23449999e+11
|
||||
check_float( 1.2345e+12f, "1.2345e+12" ); // 1.23450006e+12
|
||||
check_float( 1.2345e+13f, "1.2345e+13" ); // 1.23449995e+13
|
||||
check_float( 1.2345e+14f, "1.2345e+14" ); // 1.23450002e+14
|
||||
check_float( 1.2345e+15f, "1.2345e+15" ); // 1.23450003e+15
|
||||
check_float( 1.2345e+16f, "1.2345e+16" ); // 1.23449998e+16
|
||||
check_float( 1.2345e+17f, "1.2345e+17" ); // 1.23449996e+17
|
||||
check_float( 1.2345e+18f, "1.2345e+18" ); // 1.23450004e+18
|
||||
check_float( 1.2345e+19f, "1.2345e+19" ); // 1.23449999e+19
|
||||
check_float( 1.2345e+20f, "1.2345e+20" ); // 1.23449999e+20
|
||||
check_float( 1.2345e+21f, "1.2345e+21" ); // 1.23449999e+21
|
||||
check_float( 1.2345e+22f, "1.2345e+22" ); // 1.23450005e+22
|
||||
}
|
||||
|
||||
SECTION("double precision")
|
||||
{
|
||||
auto check_double = [](double number, const std::string & expected)
|
||||
{
|
||||
std::array<char, 33> buf{};
|
||||
char* end = nlohmann::detail::to_chars(buf.data(), buf.data() + 32, number);
|
||||
std::string actual(buf.data(), end);
|
||||
|
||||
CHECK(actual == expected);
|
||||
};
|
||||
// dtoa %.15g %.17g shortest
|
||||
check_double( -1.2345e-22, "-1.2345e-22" ); // -1.2345e-22 -1.2345000000000001e-22 -1.2345e-22
|
||||
check_double( -1.2345e-21, "-1.2345e-21" ); // -1.2345e-21 -1.2345000000000001e-21 -1.2345e-21
|
||||
check_double( -1.2345e-20, "-1.2345e-20" ); // -1.2345e-20 -1.2345e-20 -1.2345e-20
|
||||
check_double( -1.2345e-19, "-1.2345e-19" ); // -1.2345e-19 -1.2345000000000001e-19 -1.2345e-19
|
||||
check_double( -1.2345e-18, "-1.2345e-18" ); // -1.2345e-18 -1.2345000000000001e-18 -1.2345e-18
|
||||
check_double( -1.2345e-17, "-1.2345e-17" ); // -1.2345e-17 -1.2345e-17 -1.2345e-17
|
||||
check_double( -1.2345e-16, "-1.2345e-16" ); // -1.2345e-16 -1.2344999999999999e-16 -1.2345e-16
|
||||
check_double( -1.2345e-15, "-1.2345e-15" ); // -1.2345e-15 -1.2345e-15 -1.2345e-15
|
||||
check_double( -1.2345e-14, "-1.2345e-14" ); // -1.2345e-14 -1.2345e-14 -1.2345e-14
|
||||
check_double( -1.2345e-13, "-1.2345e-13" ); // -1.2345e-13 -1.2344999999999999e-13 -1.2345e-13
|
||||
check_double( -1.2345e-12, "-1.2345e-12" ); // -1.2345e-12 -1.2345e-12 -1.2345e-12
|
||||
check_double( -1.2345e-11, "-1.2345e-11" ); // -1.2345e-11 -1.2345e-11 -1.2345e-11
|
||||
check_double( -1.2345e-10, "-1.2345e-10" ); // -1.2345e-10 -1.2345e-10 -1.2345e-10
|
||||
check_double( -1.2345e-9, "-1.2345e-09" ); // -1.2345e-09 -1.2345e-09 -1.2345e-9
|
||||
check_double( -1.2345e-8, "-1.2345e-08" ); // -1.2345e-08 -1.2345000000000001e-08 -1.2345e-8
|
||||
check_double( -1.2345e-7, "-1.2345e-07" ); // -1.2345e-07 -1.2345000000000001e-07 -1.2345e-7
|
||||
check_double( -1.2345e-6, "-1.2345e-06" ); // -1.2345e-06 -1.2345e-06 -1.2345e-6
|
||||
check_double( -1.2345e-5, "-1.2345e-05" ); // -1.2345e-05 -1.2345e-05 -1.2345e-5
|
||||
check_double( -1.2345e-4, "-0.00012345" ); // -0.00012345 -0.00012344999999999999 -0.00012345
|
||||
check_double( -1.2345e-3, "-0.0012345" ); // -0.0012345 -0.0012344999999999999 -0.0012345
|
||||
check_double( -1.2345e-2, "-0.012345" ); // -0.012345 -0.012345 -0.012345
|
||||
check_double( -1.2345e-1, "-0.12345" ); // -0.12345 -0.12345 -0.12345
|
||||
check_double( -0.0, "-0.0" ); // -0 -0 -0
|
||||
check_double( 0.0, "0.0" ); // 0 0 0
|
||||
check_double( 1.2345e+0, "1.2345" ); // 1.2345 1.2344999999999999 1.2345
|
||||
check_double( 1.2345e+1, "12.345" ); // 12.345 12.345000000000001 12.345
|
||||
check_double( 1.2345e+2, "123.45" ); // 123.45 123.45 123.45
|
||||
check_double( 1.2345e+3, "1234.5" ); // 1234.5 1234.5 1234.5
|
||||
check_double( 1.2345e+4, "12345.0" ); // 12345 12345 12345
|
||||
check_double( 1.2345e+5, "123450.0" ); // 123450 123450 123450
|
||||
check_double( 1.2345e+6, "1234500.0" ); // 1234500 1234500 1234500
|
||||
check_double( 1.2345e+7, "12345000.0" ); // 12345000 12345000 12345000
|
||||
check_double( 1.2345e+8, "123450000.0" ); // 123450000 123450000 123450000
|
||||
check_double( 1.2345e+9, "1234500000.0" ); // 1234500000 1234500000 1234500000
|
||||
check_double( 1.2345e+10, "12345000000.0" ); // 12345000000 12345000000 12345000000
|
||||
check_double( 1.2345e+11, "123450000000.0" ); // 123450000000 123450000000 123450000000
|
||||
check_double( 1.2345e+12, "1234500000000.0" ); // 1234500000000 1234500000000 1234500000000
|
||||
check_double( 1.2345e+13, "12345000000000.0" ); // 12345000000000 12345000000000 12345000000000
|
||||
check_double( 1.2345e+14, "123450000000000.0" ); // 123450000000000 123450000000000 123450000000000
|
||||
check_double( 1.2345e+15, "1.2345e+15" ); // 1.2345e+15 1234500000000000 1.2345e15
|
||||
check_double( 1.2345e+16, "1.2345e+16" ); // 1.2345e+16 12345000000000000 1.2345e16
|
||||
check_double( 1.2345e+17, "1.2345e+17" ); // 1.2345e+17 1.2345e+17 1.2345e17
|
||||
check_double( 1.2345e+18, "1.2345e+18" ); // 1.2345e+18 1.2345e+18 1.2345e18
|
||||
check_double( 1.2345e+19, "1.2345e+19" ); // 1.2345e+19 1.2345e+19 1.2345e19
|
||||
check_double( 1.2345e+20, "1.2345e+20" ); // 1.2345e+20 1.2345e+20 1.2345e20
|
||||
check_double( 1.2345e+21, "1.2344999999999999e+21" ); // 1.2345e+21 1.2344999999999999e+21 1.2345e21
|
||||
check_double( 1.2345e+22, "1.2345e+22" ); // 1.2345e+22 1.2345e+22 1.2345e22
|
||||
}
|
||||
|
||||
SECTION("integer")
|
||||
{
|
||||
auto check_integer = [](std::int64_t number, const std::string & expected)
|
||||
{
|
||||
nlohmann::json j = number;
|
||||
CHECK(j.dump() == expected);
|
||||
};
|
||||
|
||||
// edge cases
|
||||
check_integer(INT64_MIN, "-9223372036854775808");
|
||||
check_integer(INT64_MAX, "9223372036854775807");
|
||||
|
||||
// few random big integers
|
||||
check_integer(-3456789012345678901LL, "-3456789012345678901");
|
||||
check_integer(3456789012345678901LL, "3456789012345678901");
|
||||
check_integer(-5678901234567890123LL, "-5678901234567890123");
|
||||
check_integer(5678901234567890123LL, "5678901234567890123");
|
||||
|
||||
// integers with various digit counts
|
||||
check_integer(-1000000000000000000LL, "-1000000000000000000");
|
||||
check_integer(-100000000000000000LL, "-100000000000000000");
|
||||
check_integer(-10000000000000000LL, "-10000000000000000");
|
||||
check_integer(-1000000000000000LL, "-1000000000000000");
|
||||
check_integer(-100000000000000LL, "-100000000000000");
|
||||
check_integer(-10000000000000LL, "-10000000000000");
|
||||
check_integer(-1000000000000LL, "-1000000000000");
|
||||
check_integer(-100000000000LL, "-100000000000");
|
||||
check_integer(-10000000000LL, "-10000000000");
|
||||
check_integer(-1000000000LL, "-1000000000");
|
||||
check_integer(-100000000LL, "-100000000");
|
||||
check_integer(-10000000LL, "-10000000");
|
||||
check_integer(-1000000LL, "-1000000");
|
||||
check_integer(-100000LL, "-100000");
|
||||
check_integer(-10000LL, "-10000");
|
||||
check_integer(-1000LL, "-1000");
|
||||
check_integer(-100LL, "-100");
|
||||
check_integer(-10LL, "-10");
|
||||
check_integer(-1LL, "-1");
|
||||
check_integer(0, "0");
|
||||
check_integer(1LL, "1");
|
||||
check_integer(10LL, "10");
|
||||
check_integer(100LL, "100");
|
||||
check_integer(1000LL, "1000");
|
||||
check_integer(10000LL, "10000");
|
||||
check_integer(100000LL, "100000");
|
||||
check_integer(1000000LL, "1000000");
|
||||
check_integer(10000000LL, "10000000");
|
||||
check_integer(100000000LL, "100000000");
|
||||
check_integer(1000000000LL, "1000000000");
|
||||
check_integer(10000000000LL, "10000000000");
|
||||
check_integer(100000000000LL, "100000000000");
|
||||
check_integer(1000000000000LL, "1000000000000");
|
||||
check_integer(10000000000000LL, "10000000000000");
|
||||
check_integer(100000000000000LL, "100000000000000");
|
||||
check_integer(1000000000000000LL, "1000000000000000");
|
||||
check_integer(10000000000000000LL, "10000000000000000");
|
||||
check_integer(100000000000000000LL, "100000000000000000");
|
||||
check_integer(1000000000000000000LL, "1000000000000000000");
|
||||
}
|
||||
}
|
||||
2570
vendor/json/test/src/unit-ubjson.cpp
vendored
Normal file
845
vendor/json/test/src/unit-udt.cpp
vendored
Normal file
@@ -0,0 +1,845 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
#include <array>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
namespace udt
|
||||
{
|
||||
enum class country
|
||||
{
|
||||
china,
|
||||
france,
|
||||
russia
|
||||
};
|
||||
|
||||
struct age
|
||||
{
|
||||
int m_val;
|
||||
age(int rhs = 0) : m_val(rhs) {}
|
||||
};
|
||||
|
||||
struct name
|
||||
{
|
||||
std::string m_val;
|
||||
name(const std::string rhs = "") : m_val(rhs) {}
|
||||
};
|
||||
|
||||
struct address
|
||||
{
|
||||
std::string m_val;
|
||||
address(const std::string rhs = "") : m_val(rhs) {}
|
||||
};
|
||||
|
||||
struct person
|
||||
{
|
||||
age m_age;
|
||||
name m_name;
|
||||
country m_country;
|
||||
person() : m_age(), m_name(), m_country() {}
|
||||
person(const age& a, const name& n, const country& c) : m_age(a), m_name(n), m_country(c) {}
|
||||
};
|
||||
|
||||
struct contact
|
||||
{
|
||||
person m_person;
|
||||
address m_address;
|
||||
contact() : m_person(), m_address() {}
|
||||
contact(const person& p, const address& a) : m_person(p), m_address(a) {}
|
||||
};
|
||||
|
||||
struct contact_book
|
||||
{
|
||||
name m_book_name;
|
||||
std::vector<contact> m_contacts;
|
||||
contact_book() : m_book_name(), m_contacts() {}
|
||||
contact_book(const name& n, const std::vector<contact>& c) : m_book_name(n), m_contacts(c) {}
|
||||
};
|
||||
}
|
||||
|
||||
// to_json methods
|
||||
namespace udt
|
||||
{
|
||||
// templates because of the custom_json tests (see below)
|
||||
template <typename BasicJsonType>
|
||||
static void to_json(BasicJsonType& j, age a)
|
||||
{
|
||||
j = a.m_val;
|
||||
}
|
||||
|
||||
template <typename BasicJsonType>
|
||||
static void to_json(BasicJsonType& j, const name& n)
|
||||
{
|
||||
j = n.m_val;
|
||||
}
|
||||
|
||||
template <typename BasicJsonType>
|
||||
static void to_json(BasicJsonType& j, country c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case country::china:
|
||||
j = "中华人民共和国";
|
||||
return;
|
||||
case country::france:
|
||||
j = "France";
|
||||
return;
|
||||
case country::russia:
|
||||
j = "Российская Федерация";
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename BasicJsonType>
|
||||
static void to_json(BasicJsonType& j, const person& p)
|
||||
{
|
||||
j = BasicJsonType{{"age", p.m_age}, {"name", p.m_name}, {"country", p.m_country}};
|
||||
}
|
||||
|
||||
static void to_json(nlohmann::json& j, const address& a)
|
||||
{
|
||||
j = a.m_val;
|
||||
}
|
||||
|
||||
static void to_json(nlohmann::json& j, const contact& c)
|
||||
{
|
||||
j = json{{"person", c.m_person}, {"address", c.m_address}};
|
||||
}
|
||||
|
||||
static void to_json(nlohmann::json& j, const contact_book& cb)
|
||||
{
|
||||
j = json{{"name", cb.m_book_name}, {"contacts", cb.m_contacts}};
|
||||
}
|
||||
|
||||
// operators
|
||||
static bool operator==(age lhs, age rhs)
|
||||
{
|
||||
return lhs.m_val == rhs.m_val;
|
||||
}
|
||||
|
||||
static bool operator==(const address& lhs, const address& rhs)
|
||||
{
|
||||
return lhs.m_val == rhs.m_val;
|
||||
}
|
||||
|
||||
static bool operator==(const name& lhs, const name& rhs)
|
||||
{
|
||||
return lhs.m_val == rhs.m_val;
|
||||
}
|
||||
|
||||
static bool operator==(const person& lhs, const person& rhs)
|
||||
{
|
||||
return std::tie(lhs.m_name, lhs.m_age) == std::tie(rhs.m_name, rhs.m_age);
|
||||
}
|
||||
|
||||
static bool operator==(const contact& lhs, const contact& rhs)
|
||||
{
|
||||
return std::tie(lhs.m_person, lhs.m_address) ==
|
||||
std::tie(rhs.m_person, rhs.m_address);
|
||||
}
|
||||
|
||||
static bool operator==(const contact_book& lhs, const contact_book& rhs)
|
||||
{
|
||||
return std::tie(lhs.m_book_name, lhs.m_contacts) ==
|
||||
std::tie(rhs.m_book_name, rhs.m_contacts);
|
||||
}
|
||||
}
|
||||
|
||||
// from_json methods
|
||||
namespace udt
|
||||
{
|
||||
template <typename BasicJsonType>
|
||||
static void from_json(const BasicJsonType& j, age& a)
|
||||
{
|
||||
a.m_val = j.template get<int>();
|
||||
}
|
||||
|
||||
template <typename BasicJsonType>
|
||||
static void from_json(const BasicJsonType& j, name& n)
|
||||
{
|
||||
n.m_val = j.template get<std::string>();
|
||||
}
|
||||
|
||||
template <typename BasicJsonType>
|
||||
static void from_json(const BasicJsonType& j, country& c)
|
||||
{
|
||||
const auto str = j.template get<std::string>();
|
||||
static const std::map<std::string, country> m =
|
||||
{
|
||||
{"中华人民共和国", country::china},
|
||||
{"France", country::france},
|
||||
{"Российская Федерация", country::russia}
|
||||
};
|
||||
|
||||
const auto it = m.find(str);
|
||||
// TODO test exceptions
|
||||
c = it->second;
|
||||
}
|
||||
|
||||
template <typename BasicJsonType>
|
||||
static void from_json(const BasicJsonType& j, person& p)
|
||||
{
|
||||
p.m_age = j["age"].template get<age>();
|
||||
p.m_name = j["name"].template get<name>();
|
||||
p.m_country = j["country"].template get<country>();
|
||||
}
|
||||
|
||||
static void from_json(const nlohmann::json& j, address& a)
|
||||
{
|
||||
a.m_val = j.get<std::string>();
|
||||
}
|
||||
|
||||
static void from_json(const nlohmann::json& j, contact& c)
|
||||
{
|
||||
c.m_person = j["person"].get<person>();
|
||||
c.m_address = j["address"].get<address>();
|
||||
}
|
||||
|
||||
static void from_json(const nlohmann::json& j, contact_book& cb)
|
||||
{
|
||||
cb.m_book_name = j["name"].get<name>();
|
||||
cb.m_contacts = j["contacts"].get<std::vector<contact>>();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("basic usage" * doctest::test_suite("udt"))
|
||||
{
|
||||
|
||||
// a bit narcissistic maybe :) ?
|
||||
const udt::age a
|
||||
{
|
||||
23
|
||||
};
|
||||
const udt::name n{"theo"};
|
||||
const udt::country c{udt::country::france};
|
||||
const udt::person sfinae_addict{a, n, c};
|
||||
const udt::person senior_programmer{{42}, {"王芳"}, udt::country::china};
|
||||
const udt::address addr{"Paris"};
|
||||
const udt::contact cpp_programmer{sfinae_addict, addr};
|
||||
const udt::contact_book book{{"C++"}, {cpp_programmer, {senior_programmer, addr}}};
|
||||
|
||||
SECTION("conversion to json via free-functions")
|
||||
{
|
||||
CHECK(json(a) == json(23));
|
||||
CHECK(json(n) == json("theo"));
|
||||
CHECK(json(c) == json("France"));
|
||||
CHECK(json(sfinae_addict) == R"({"name":"theo", "age":23, "country":"France"})"_json);
|
||||
CHECK(json("Paris") == json(addr));
|
||||
CHECK(json(cpp_programmer) ==
|
||||
R"({"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"})"_json);
|
||||
|
||||
CHECK(
|
||||
json(book) ==
|
||||
R"({"name":"C++", "contacts" : [{"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"}, {"person" : {"age":42, "country":"中华人民共和国", "name":"王芳"}, "address":"Paris"}]})"_json);
|
||||
|
||||
}
|
||||
|
||||
SECTION("conversion from json via free-functions")
|
||||
{
|
||||
const auto big_json =
|
||||
R"({"name":"C++", "contacts" : [{"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"}, {"person" : {"age":42, "country":"中华人民共和国", "name":"王芳"}, "address":"Paris"}]})"_json;
|
||||
SECTION("via explicit calls to get")
|
||||
{
|
||||
const auto parsed_book = big_json.get<udt::contact_book>();
|
||||
const auto book_name = big_json["name"].get<udt::name>();
|
||||
const auto contacts =
|
||||
big_json["contacts"].get<std::vector<udt::contact>>();
|
||||
const auto contact_json = big_json["contacts"].at(0);
|
||||
const auto contact = contact_json.get<udt::contact>();
|
||||
const auto person = contact_json["person"].get<udt::person>();
|
||||
const auto address = contact_json["address"].get<udt::address>();
|
||||
const auto age = contact_json["person"]["age"].get<udt::age>();
|
||||
const auto country =
|
||||
contact_json["person"]["country"].get<udt::country>();
|
||||
const auto name = contact_json["person"]["name"].get<udt::name>();
|
||||
|
||||
CHECK(age == a);
|
||||
CHECK(name == n);
|
||||
CHECK(country == c);
|
||||
CHECK(address == addr);
|
||||
CHECK(person == sfinae_addict);
|
||||
CHECK(contact == cpp_programmer);
|
||||
CHECK(contacts == book.m_contacts);
|
||||
CHECK(book_name == udt::name{"C++"});
|
||||
CHECK(book == parsed_book);
|
||||
}
|
||||
|
||||
SECTION("via explicit calls to get_to")
|
||||
{
|
||||
udt::person person;
|
||||
udt::name name;
|
||||
|
||||
json person_json = big_json["contacts"][0]["person"];
|
||||
CHECK(person_json.get_to(person) == sfinae_addict);
|
||||
|
||||
// correct reference gets returned
|
||||
person_json["name"].get_to(name).m_val = "new name";
|
||||
CHECK(name.m_val == "new name");
|
||||
}
|
||||
|
||||
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||
SECTION("implicit conversions")
|
||||
{
|
||||
const udt::contact_book parsed_book = big_json;
|
||||
const udt::name book_name = big_json["name"];
|
||||
const std::vector<udt::contact> contacts = big_json["contacts"];
|
||||
const auto contact_json = big_json["contacts"].at(0);
|
||||
const udt::contact contact = contact_json;
|
||||
const udt::person person = contact_json["person"];
|
||||
const udt::address address = contact_json["address"];
|
||||
const udt::age age = contact_json["person"]["age"];
|
||||
const udt::country country = contact_json["person"]["country"];
|
||||
const udt::name name = contact_json["person"]["name"];
|
||||
|
||||
CHECK(age == a);
|
||||
CHECK(name == n);
|
||||
CHECK(country == c);
|
||||
CHECK(address == addr);
|
||||
CHECK(person == sfinae_addict);
|
||||
CHECK(contact == cpp_programmer);
|
||||
CHECK(contacts == book.m_contacts);
|
||||
CHECK(book_name == udt::name{"C++"});
|
||||
CHECK(book == parsed_book);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
namespace udt
|
||||
{
|
||||
struct legacy_type
|
||||
{
|
||||
std::string number;
|
||||
legacy_type() : number() {}
|
||||
legacy_type(const std::string& n) : number(n) {}
|
||||
};
|
||||
}
|
||||
|
||||
namespace nlohmann
|
||||
{
|
||||
template <typename T>
|
||||
struct adl_serializer<std::shared_ptr<T>>
|
||||
{
|
||||
static void to_json(json& j, const std::shared_ptr<T>& opt)
|
||||
{
|
||||
if (opt)
|
||||
{
|
||||
j = *opt;
|
||||
}
|
||||
else
|
||||
{
|
||||
j = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static void from_json(const json& j, std::shared_ptr<T>& opt)
|
||||
{
|
||||
if (j.is_null())
|
||||
{
|
||||
opt = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
opt.reset(new T(j.get<T>()));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct adl_serializer<udt::legacy_type>
|
||||
{
|
||||
static void to_json(json& j, const udt::legacy_type& l)
|
||||
{
|
||||
j = std::stoi(l.number);
|
||||
}
|
||||
|
||||
static void from_json(const json& j, udt::legacy_type& l)
|
||||
{
|
||||
l.number = std::to_string(j.get<int>());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("adl_serializer specialization" * doctest::test_suite("udt"))
|
||||
{
|
||||
SECTION("partial specialization")
|
||||
{
|
||||
SECTION("to_json")
|
||||
{
|
||||
std::shared_ptr<udt::person> optPerson;
|
||||
|
||||
json j = optPerson;
|
||||
CHECK(j.is_null());
|
||||
|
||||
optPerson.reset(new udt::person{{42}, {"John Doe"}, udt::country::russia});
|
||||
j = optPerson;
|
||||
CHECK_FALSE(j.is_null());
|
||||
|
||||
CHECK(j.get<udt::person>() == *optPerson);
|
||||
}
|
||||
|
||||
SECTION("from_json")
|
||||
{
|
||||
auto person = udt::person{{42}, {"John Doe"}, udt::country::russia};
|
||||
json j = person;
|
||||
|
||||
auto optPerson = j.get<std::shared_ptr<udt::person>>();
|
||||
REQUIRE(optPerson);
|
||||
CHECK(*optPerson == person);
|
||||
|
||||
j = nullptr;
|
||||
optPerson = j.get<std::shared_ptr<udt::person>>();
|
||||
CHECK(!optPerson);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("total specialization")
|
||||
{
|
||||
SECTION("to_json")
|
||||
{
|
||||
udt::legacy_type lt{"4242"};
|
||||
|
||||
json j = lt;
|
||||
CHECK(j.get<int>() == 4242);
|
||||
}
|
||||
|
||||
SECTION("from_json")
|
||||
{
|
||||
json j = 4242;
|
||||
auto lt = j.get<udt::legacy_type>();
|
||||
CHECK(lt.number == "4242");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace nlohmann
|
||||
{
|
||||
template <>
|
||||
struct adl_serializer<std::vector<float>>
|
||||
{
|
||||
using type = std::vector<float>;
|
||||
static void to_json(json& j, const type&)
|
||||
{
|
||||
j = "hijacked!";
|
||||
}
|
||||
|
||||
static void from_json(const json&, type& opt)
|
||||
{
|
||||
opt = {42.0, 42.0, 42.0};
|
||||
}
|
||||
|
||||
// preferred version
|
||||
static type from_json(const json&)
|
||||
{
|
||||
return {4.0, 5.0, 6.0};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("even supported types can be specialized" * doctest::test_suite("udt"))
|
||||
{
|
||||
json j = std::vector<float> {1.0, 2.0, 3.0};
|
||||
CHECK(j.dump() == R"("hijacked!")");
|
||||
auto f = j.get<std::vector<float>>();
|
||||
// the single argument from_json method is preferred
|
||||
CHECK((f == std::vector<float> {4.0, 5.0, 6.0}));
|
||||
}
|
||||
|
||||
namespace nlohmann
|
||||
{
|
||||
template <typename T>
|
||||
struct adl_serializer<std::unique_ptr<T>>
|
||||
{
|
||||
static void to_json(json& j, const std::unique_ptr<T>& opt)
|
||||
{
|
||||
if (opt)
|
||||
{
|
||||
j = *opt;
|
||||
}
|
||||
else
|
||||
{
|
||||
j = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// this is the overload needed for non-copyable types,
|
||||
static std::unique_ptr<T> from_json(const json& j)
|
||||
{
|
||||
if (j.is_null())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::unique_ptr<T>(new T(j.get<T>()));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("Non-copyable types" * doctest::test_suite("udt"))
|
||||
{
|
||||
SECTION("to_json")
|
||||
{
|
||||
std::unique_ptr<udt::person> optPerson;
|
||||
|
||||
json j = optPerson;
|
||||
CHECK(j.is_null());
|
||||
|
||||
optPerson.reset(new udt::person{{42}, {"John Doe"}, udt::country::russia});
|
||||
j = optPerson;
|
||||
CHECK_FALSE(j.is_null());
|
||||
|
||||
CHECK(j.get<udt::person>() == *optPerson);
|
||||
}
|
||||
|
||||
SECTION("from_json")
|
||||
{
|
||||
auto person = udt::person{{42}, {"John Doe"}, udt::country::russia};
|
||||
json j = person;
|
||||
|
||||
auto optPerson = j.get<std::unique_ptr<udt::person>>();
|
||||
REQUIRE(optPerson);
|
||||
CHECK(*optPerson == person);
|
||||
|
||||
j = nullptr;
|
||||
optPerson = j.get<std::unique_ptr<udt::person>>();
|
||||
CHECK(!optPerson);
|
||||
}
|
||||
}
|
||||
|
||||
// custom serializer - advanced usage
|
||||
// pack structs that are pod-types (but not scalar types)
|
||||
// relies on adl for any other type
|
||||
template <typename T, typename = void>
|
||||
struct pod_serializer
|
||||
{
|
||||
// use adl for non-pods, or scalar types
|
||||
template <
|
||||
typename BasicJsonType, typename U = T,
|
||||
typename std::enable_if <
|
||||
!(std::is_pod<U>::value && std::is_class<U>::value), int >::type = 0 >
|
||||
static void from_json(const BasicJsonType& j, U& t)
|
||||
{
|
||||
using nlohmann::from_json;
|
||||
from_json(j, t);
|
||||
}
|
||||
|
||||
// special behaviour for pods
|
||||
template < typename BasicJsonType, typename U = T,
|
||||
typename std::enable_if <
|
||||
std::is_pod<U>::value && std::is_class<U>::value, int >::type = 0 >
|
||||
static void from_json(const BasicJsonType& j, U& t)
|
||||
{
|
||||
std::uint64_t value;
|
||||
// TODO The following block is no longer relevant in this serializer, make another one that shows the issue
|
||||
// the problem arises only when one from_json method is defined without any constraint
|
||||
//
|
||||
// Why cannot we simply use: j.get<std::uint64_t>() ?
|
||||
// Well, with the current experiment, the get method looks for a from_json
|
||||
// function, which we are currently defining!
|
||||
// This would end up in a stack overflow. Calling nlohmann::from_json is a
|
||||
// workaround (is it?).
|
||||
// I shall find a good way to avoid this once all constructors are converted
|
||||
// to free methods
|
||||
//
|
||||
// In short, constructing a json by constructor calls to_json
|
||||
// calling get calls from_json, for now, we cannot do this in custom
|
||||
// serializers
|
||||
nlohmann::from_json(j, value);
|
||||
auto bytes = static_cast<char*>(static_cast<void*>(&value));
|
||||
std::memcpy(&t, bytes, sizeof(value));
|
||||
}
|
||||
|
||||
template <
|
||||
typename BasicJsonType, typename U = T,
|
||||
typename std::enable_if <
|
||||
!(std::is_pod<U>::value && std::is_class<U>::value), int >::type = 0 >
|
||||
static void to_json(BasicJsonType& j, const T& t)
|
||||
{
|
||||
using nlohmann::to_json;
|
||||
to_json(j, t);
|
||||
}
|
||||
|
||||
template < typename BasicJsonType, typename U = T,
|
||||
typename std::enable_if <
|
||||
std::is_pod<U>::value && std::is_class<U>::value, int >::type = 0 >
|
||||
static void to_json(BasicJsonType& j, const T& t) noexcept
|
||||
{
|
||||
auto bytes = static_cast< const unsigned char*>(static_cast<const void*>(&t));
|
||||
std::uint64_t value;
|
||||
std::memcpy(&value, bytes, sizeof(value));
|
||||
nlohmann::to_json(j, value);
|
||||
}
|
||||
};
|
||||
|
||||
namespace udt
|
||||
{
|
||||
struct small_pod
|
||||
{
|
||||
int begin;
|
||||
char middle;
|
||||
short end;
|
||||
};
|
||||
|
||||
struct non_pod
|
||||
{
|
||||
std::string s;
|
||||
non_pod() : s() {}
|
||||
non_pod(const std::string& S) : s(S) {}
|
||||
};
|
||||
|
||||
template <typename BasicJsonType>
|
||||
static void to_json(BasicJsonType& j, const non_pod& np)
|
||||
{
|
||||
j = np.s;
|
||||
}
|
||||
|
||||
template <typename BasicJsonType>
|
||||
static void from_json(const BasicJsonType& j, non_pod& np)
|
||||
{
|
||||
np.s = j.template get<std::string>();
|
||||
}
|
||||
|
||||
static bool operator==(small_pod lhs, small_pod rhs) noexcept
|
||||
{
|
||||
return std::tie(lhs.begin, lhs.middle, lhs.end) ==
|
||||
std::tie(rhs.begin, rhs.middle, rhs.end);
|
||||
}
|
||||
|
||||
static bool operator==(const non_pod& lhs, const non_pod& rhs) noexcept
|
||||
{
|
||||
return lhs.s == rhs.s;
|
||||
}
|
||||
|
||||
static std::ostream& operator<<(std::ostream& os, small_pod l)
|
||||
{
|
||||
return os << "begin: " << l.begin << ", middle: " << l.middle << ", end: " << l.end;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("custom serializer for pods" * doctest::test_suite("udt"))
|
||||
{
|
||||
using custom_json =
|
||||
nlohmann::basic_json<std::map, std::vector, std::string, bool,
|
||||
std::int64_t, std::uint64_t, double, std::allocator, pod_serializer>;
|
||||
|
||||
auto p = udt::small_pod{42, '/', 42};
|
||||
custom_json j = p;
|
||||
|
||||
auto p2 = j.get<udt::small_pod>();
|
||||
|
||||
CHECK(p == p2);
|
||||
|
||||
auto np = udt::non_pod{{"non-pod"}};
|
||||
custom_json j2 = np;
|
||||
auto np2 = j2.get<udt::non_pod>();
|
||||
CHECK(np == np2);
|
||||
}
|
||||
|
||||
template <typename T, typename>
|
||||
struct another_adl_serializer;
|
||||
|
||||
using custom_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, double, std::allocator, another_adl_serializer>;
|
||||
|
||||
template <typename T, typename>
|
||||
struct another_adl_serializer
|
||||
{
|
||||
static void from_json(const custom_json& j, T& t)
|
||||
{
|
||||
using nlohmann::from_json;
|
||||
from_json(j, t);
|
||||
}
|
||||
|
||||
static void to_json(custom_json& j, const T& t)
|
||||
{
|
||||
using nlohmann::to_json;
|
||||
to_json(j, t);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CASE("custom serializer that does adl by default" * doctest::test_suite("udt"))
|
||||
{
|
||||
auto me = udt::person{{23}, {"theo"}, udt::country::france};
|
||||
|
||||
json j = me;
|
||||
custom_json cj = me;
|
||||
|
||||
CHECK(j.dump() == cj.dump());
|
||||
|
||||
CHECK(me == j.get<udt::person>());
|
||||
CHECK(me == cj.get<udt::person>());
|
||||
}
|
||||
|
||||
TEST_CASE("different basic_json types conversions")
|
||||
{
|
||||
SECTION("null")
|
||||
{
|
||||
json j;
|
||||
custom_json cj = j;
|
||||
CHECK(cj == nullptr);
|
||||
}
|
||||
|
||||
SECTION("boolean")
|
||||
{
|
||||
json j = true;
|
||||
custom_json cj = j;
|
||||
CHECK(cj == true);
|
||||
}
|
||||
|
||||
SECTION("discarded")
|
||||
{
|
||||
json j(json::value_t::discarded);
|
||||
custom_json cj;
|
||||
CHECK_NOTHROW(cj = j);
|
||||
CHECK(cj.type() == custom_json::value_t::discarded);
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
{
|
||||
json j = {1, 2, 3};
|
||||
custom_json cj = j;
|
||||
CHECK((cj == std::vector<int> {1, 2, 3}));
|
||||
}
|
||||
|
||||
SECTION("integer")
|
||||
{
|
||||
json j = 42;
|
||||
custom_json cj = j;
|
||||
CHECK(cj == 42);
|
||||
}
|
||||
|
||||
SECTION("float")
|
||||
{
|
||||
json j = 42.0;
|
||||
custom_json cj = j;
|
||||
CHECK(cj == 42.0);
|
||||
}
|
||||
|
||||
SECTION("unsigned")
|
||||
{
|
||||
json j = 42u;
|
||||
custom_json cj = j;
|
||||
CHECK(cj == 42u);
|
||||
}
|
||||
|
||||
SECTION("string")
|
||||
{
|
||||
json j = "forty-two";
|
||||
custom_json cj = j;
|
||||
CHECK(cj == "forty-two");
|
||||
}
|
||||
|
||||
SECTION("binary")
|
||||
{
|
||||
json j = json::binary({1, 2, 3}, 42);
|
||||
custom_json cj = j;
|
||||
CHECK(cj.get_binary().subtype() == 42);
|
||||
std::vector<std::uint8_t> cv = cj.get_binary();
|
||||
std::vector<std::uint8_t> v = j.get_binary();
|
||||
CHECK(cv == v);
|
||||
}
|
||||
|
||||
SECTION("object")
|
||||
{
|
||||
json j = {{"forty", "two"}};
|
||||
custom_json cj = j;
|
||||
auto m = j.get<std::map<std::string, std::string>>();
|
||||
CHECK(cj == m);
|
||||
}
|
||||
|
||||
SECTION("get<custom_json>")
|
||||
{
|
||||
json j = 42;
|
||||
custom_json cj = j.get<custom_json>();
|
||||
CHECK(cj == 42);
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
struct incomplete;
|
||||
|
||||
// std::is_constructible is broken on macOS' libc++
|
||||
// use the cppreference implementation
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct is_constructible_patched : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_constructible_patched<T, decltype(void(json(std::declval<T>())))> : std::true_type {};
|
||||
}
|
||||
|
||||
TEST_CASE("an incomplete type does not trigger a compiler error in non-evaluated context" * doctest::test_suite("udt"))
|
||||
{
|
||||
static_assert(!is_constructible_patched<json, incomplete>::value, "");
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class Evil
|
||||
{
|
||||
public:
|
||||
Evil() = default;
|
||||
template <typename T>
|
||||
Evil(T t) : m_i(sizeof(t)) {}
|
||||
|
||||
int m_i = 0;
|
||||
};
|
||||
|
||||
void from_json(const json&, Evil&) {}
|
||||
}
|
||||
|
||||
TEST_CASE("Issue #924")
|
||||
{
|
||||
// Prevent get<std::vector<Evil>>() to throw
|
||||
auto j = json::array();
|
||||
|
||||
CHECK_NOTHROW(j.get<Evil>());
|
||||
CHECK_NOTHROW(j.get<std::vector<Evil>>());
|
||||
|
||||
// silence Wunused-template warnings
|
||||
Evil e(1);
|
||||
CHECK(e.m_i >= 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Issue #1237")
|
||||
{
|
||||
struct non_convertible_type {};
|
||||
static_assert(!std::is_convertible<json, non_convertible_type>::value, "");
|
||||
}
|
||||
330
vendor/json/test/src/unit-udt_macro.cpp
vendored
Normal file
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
namespace persons
|
||||
{
|
||||
class person_with_private_data
|
||||
{
|
||||
private:
|
||||
std::string name = "";
|
||||
int age = 0;
|
||||
json metadata = nullptr;
|
||||
|
||||
public:
|
||||
bool operator==(const person_with_private_data& rhs) const
|
||||
{
|
||||
return name == rhs.name && age == rhs.age && metadata == rhs.metadata;
|
||||
}
|
||||
|
||||
person_with_private_data() = default;
|
||||
person_with_private_data(std::string name_, int age_, json metadata_)
|
||||
: name(std::move(name_))
|
||||
, age(age_)
|
||||
, metadata(std::move(metadata_))
|
||||
{}
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_with_private_data, age, name, metadata)
|
||||
};
|
||||
|
||||
class person_without_private_data_1
|
||||
{
|
||||
public:
|
||||
std::string name = "";
|
||||
int age = 0;
|
||||
json metadata = nullptr;
|
||||
|
||||
bool operator==(const person_without_private_data_1& rhs) const
|
||||
{
|
||||
return name == rhs.name && age == rhs.age && metadata == rhs.metadata;
|
||||
}
|
||||
|
||||
person_without_private_data_1() = default;
|
||||
person_without_private_data_1(std::string name_, int age_, json metadata_)
|
||||
: name(std::move(name_))
|
||||
, age(age_)
|
||||
, metadata(std::move(metadata_))
|
||||
{}
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_without_private_data_1, age, name, metadata)
|
||||
};
|
||||
|
||||
class person_without_private_data_2
|
||||
{
|
||||
public:
|
||||
std::string name = "";
|
||||
int age = 0;
|
||||
json metadata = nullptr;
|
||||
|
||||
bool operator==(const person_without_private_data_2& rhs) const
|
||||
{
|
||||
return name == rhs.name && age == rhs.age && metadata == rhs.metadata;
|
||||
}
|
||||
|
||||
person_without_private_data_2() = default;
|
||||
person_without_private_data_2(std::string name_, int age_, json metadata_)
|
||||
: name(std::move(name_))
|
||||
, age(age_)
|
||||
, metadata(std::move(metadata_))
|
||||
{}
|
||||
};
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person_without_private_data_2, age, name, metadata)
|
||||
|
||||
class person_with_private_alphabet
|
||||
{
|
||||
public:
|
||||
bool operator==(const person_with_private_alphabet& other) const
|
||||
{
|
||||
return a == other.a &&
|
||||
b == other.b &&
|
||||
c == other.c &&
|
||||
d == other.d &&
|
||||
e == other.e &&
|
||||
f == other.f &&
|
||||
g == other.g &&
|
||||
h == other.h &&
|
||||
i == other.i &&
|
||||
j == other.j &&
|
||||
k == other.k &&
|
||||
l == other.l &&
|
||||
m == other.m &&
|
||||
n == other.n &&
|
||||
o == other.o &&
|
||||
p == other.p &&
|
||||
q == other.q &&
|
||||
r == other.r &&
|
||||
s == other.s &&
|
||||
t == other.t &&
|
||||
u == other.u &&
|
||||
v == other.v &&
|
||||
w == other.w &&
|
||||
x == other.x &&
|
||||
y == other.y &&
|
||||
z == other.z;
|
||||
}
|
||||
|
||||
private:
|
||||
int a = 0;
|
||||
int b = 0;
|
||||
int c = 0;
|
||||
int d = 0;
|
||||
int e = 0;
|
||||
int f = 0;
|
||||
int g = 0;
|
||||
int h = 0;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int k = 0;
|
||||
int l = 0;
|
||||
int m = 0;
|
||||
int n = 0;
|
||||
int o = 0;
|
||||
int p = 0;
|
||||
int q = 0;
|
||||
int r = 0;
|
||||
int s = 0;
|
||||
int t = 0;
|
||||
int u = 0;
|
||||
int v = 0;
|
||||
int w = 0;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int z = 0;
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_with_private_alphabet, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)
|
||||
};
|
||||
|
||||
class person_with_public_alphabet
|
||||
{
|
||||
public:
|
||||
bool operator==(const person_with_public_alphabet& other) const
|
||||
{
|
||||
return a == other.a &&
|
||||
b == other.b &&
|
||||
c == other.c &&
|
||||
d == other.d &&
|
||||
e == other.e &&
|
||||
f == other.f &&
|
||||
g == other.g &&
|
||||
h == other.h &&
|
||||
i == other.i &&
|
||||
j == other.j &&
|
||||
k == other.k &&
|
||||
l == other.l &&
|
||||
m == other.m &&
|
||||
n == other.n &&
|
||||
o == other.o &&
|
||||
p == other.p &&
|
||||
q == other.q &&
|
||||
r == other.r &&
|
||||
s == other.s &&
|
||||
t == other.t &&
|
||||
u == other.u &&
|
||||
v == other.v &&
|
||||
w == other.w &&
|
||||
x == other.x &&
|
||||
y == other.y &&
|
||||
z == other.z;
|
||||
}
|
||||
|
||||
int a = 0;
|
||||
int b = 0;
|
||||
int c = 0;
|
||||
int d = 0;
|
||||
int e = 0;
|
||||
int f = 0;
|
||||
int g = 0;
|
||||
int h = 0;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int k = 0;
|
||||
int l = 0;
|
||||
int m = 0;
|
||||
int n = 0;
|
||||
int o = 0;
|
||||
int p = 0;
|
||||
int q = 0;
|
||||
int r = 0;
|
||||
int s = 0;
|
||||
int t = 0;
|
||||
int u = 0;
|
||||
int v = 0;
|
||||
int w = 0;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int z = 0;
|
||||
};
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person_with_public_alphabet, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)
|
||||
|
||||
} // namespace persons
|
||||
|
||||
TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE", T,
|
||||
persons::person_with_private_data,
|
||||
persons::person_without_private_data_1,
|
||||
persons::person_without_private_data_2)
|
||||
{
|
||||
SECTION("person")
|
||||
{
|
||||
// serialization
|
||||
T p1("Erik", 1, {{"haircuts", 2}});
|
||||
CHECK(json(p1).dump() == "{\"age\":1,\"metadata\":{\"haircuts\":2},\"name\":\"Erik\"}");
|
||||
|
||||
// deserialization
|
||||
auto p2 = json(p1).get<T>();
|
||||
CHECK(p2 == p1);
|
||||
|
||||
// roundtrip
|
||||
CHECK(T(json(p1)) == p1);
|
||||
CHECK(json(T(json(p1))) == json(p1));
|
||||
|
||||
// check exception in case of missing field
|
||||
json j = json(p1);
|
||||
j.erase("age");
|
||||
CHECK_THROWS_WITH_AS(j.get<T>(), "[json.exception.out_of_range.403] key 'age' not found", json::out_of_range);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE_TEMPLATE("Serialization/deserialization of classes with 26 public/private member variables via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE", T,
|
||||
persons::person_with_private_alphabet,
|
||||
persons::person_with_public_alphabet)
|
||||
{
|
||||
SECTION("alphabet")
|
||||
{
|
||||
{
|
||||
T obj1;
|
||||
nlohmann::json j = obj1; //via json object
|
||||
T obj2;
|
||||
j.get_to(obj2);
|
||||
bool ok = (obj1 == obj2);
|
||||
CHECK(ok);
|
||||
}
|
||||
|
||||
{
|
||||
T obj1;
|
||||
nlohmann::json j1 = obj1; //via json string
|
||||
std::string s = j1.dump();
|
||||
nlohmann::json j2 = nlohmann::json::parse(s);
|
||||
T obj2;
|
||||
j2.get_to(obj2);
|
||||
bool ok = (obj1 == obj2);
|
||||
CHECK(ok);
|
||||
}
|
||||
|
||||
{
|
||||
T obj1;
|
||||
nlohmann::json j1 = obj1; //via msgpack
|
||||
std::vector<uint8_t> buf = nlohmann::json::to_msgpack(j1);
|
||||
nlohmann::json j2 = nlohmann::json::from_msgpack(buf);
|
||||
T obj2;
|
||||
j2.get_to(obj2);
|
||||
bool ok = (obj1 == obj2);
|
||||
CHECK(ok);
|
||||
}
|
||||
|
||||
{
|
||||
T obj1;
|
||||
nlohmann::json j1 = obj1; //via bson
|
||||
std::vector<uint8_t> buf = nlohmann::json::to_bson(j1);
|
||||
nlohmann::json j2 = nlohmann::json::from_bson(buf);
|
||||
T obj2;
|
||||
j2.get_to(obj2);
|
||||
bool ok = (obj1 == obj2);
|
||||
CHECK(ok);
|
||||
}
|
||||
|
||||
{
|
||||
T obj1;
|
||||
nlohmann::json j1 = obj1; //via cbor
|
||||
std::vector<uint8_t> buf = nlohmann::json::to_cbor(j1);
|
||||
nlohmann::json j2 = nlohmann::json::from_cbor(buf);
|
||||
T obj2;
|
||||
j2.get_to(obj2);
|
||||
bool ok = (obj1 == obj2);
|
||||
CHECK(ok);
|
||||
}
|
||||
|
||||
{
|
||||
T obj1;
|
||||
nlohmann::json j1 = obj1; //via ubjson
|
||||
std::vector<uint8_t> buf = nlohmann::json::to_ubjson(j1);
|
||||
nlohmann::json j2 = nlohmann::json::from_ubjson(buf);
|
||||
T obj2;
|
||||
j2.get_to(obj2);
|
||||
bool ok = (obj1 == obj2);
|
||||
CHECK(ok);
|
||||
}
|
||||
}
|
||||
}
|
||||
1611
vendor/json/test/src/unit-unicode.cpp
vendored
Normal file
144
vendor/json/test/src/unit-user_defined_input.cpp
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace
|
||||
{
|
||||
TEST_CASE("Use arbitrary stdlib container")
|
||||
{
|
||||
std::string raw_data = "[1,2,3,4]";
|
||||
std::list<char> data(raw_data.begin(), raw_data.end());
|
||||
|
||||
json as_json = json::parse(data.begin(), data.end());
|
||||
CHECK(as_json.at(0) == 1);
|
||||
CHECK(as_json.at(1) == 2);
|
||||
CHECK(as_json.at(2) == 3);
|
||||
CHECK(as_json.at(3) == 4);
|
||||
}
|
||||
|
||||
struct MyContainer
|
||||
{
|
||||
const char* data;
|
||||
};
|
||||
|
||||
const char* begin(const MyContainer& c)
|
||||
{
|
||||
return c.data;
|
||||
}
|
||||
|
||||
const char* end(const MyContainer& c)
|
||||
{
|
||||
return c.data + strlen(c.data);
|
||||
}
|
||||
|
||||
TEST_CASE("Custom container non-member begin/end")
|
||||
{
|
||||
|
||||
MyContainer data{"[1,2,3,4]"};
|
||||
json as_json = json::parse(data);
|
||||
CHECK(as_json.at(0) == 1);
|
||||
CHECK(as_json.at(1) == 2);
|
||||
CHECK(as_json.at(2) == 3);
|
||||
CHECK(as_json.at(3) == 4);
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Custom container member begin/end")
|
||||
{
|
||||
struct MyContainer2
|
||||
{
|
||||
const char* data;
|
||||
|
||||
const char* begin() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
const char* end() const
|
||||
{
|
||||
return data + strlen(data);
|
||||
}
|
||||
};
|
||||
|
||||
MyContainer2 data{"[1,2,3,4]"};
|
||||
json as_json = json::parse(data);
|
||||
CHECK(as_json.at(0) == 1);
|
||||
CHECK(as_json.at(1) == 2);
|
||||
CHECK(as_json.at(2) == 3);
|
||||
CHECK(as_json.at(3) == 4);
|
||||
}
|
||||
|
||||
TEST_CASE("Custom iterator")
|
||||
{
|
||||
const char* raw_data = "[1,2,3,4]";
|
||||
|
||||
struct MyIterator
|
||||
{
|
||||
using difference_type = std::size_t;
|
||||
using value_type = char;
|
||||
using pointer = const char*;
|
||||
using reference = const char&;
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
|
||||
MyIterator& operator++()
|
||||
{
|
||||
++ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
reference operator*() const
|
||||
{
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
bool operator!=(const MyIterator& rhs) const
|
||||
{
|
||||
return ptr != rhs.ptr;
|
||||
}
|
||||
|
||||
const char* ptr;
|
||||
};
|
||||
|
||||
MyIterator begin{raw_data};
|
||||
MyIterator end{raw_data + strlen(raw_data)};
|
||||
|
||||
json as_json = json::parse(begin, end);
|
||||
CHECK(as_json.at(0) == 1);
|
||||
CHECK(as_json.at(1) == 2);
|
||||
CHECK(as_json.at(2) == 3);
|
||||
CHECK(as_json.at(3) == 4);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
117
vendor/json/test/src/unit-wstring.cpp
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
namespace
|
||||
{
|
||||
bool wstring_is_utf16();
|
||||
bool wstring_is_utf16()
|
||||
{
|
||||
return (std::wstring(L"💩") == std::wstring(L"\U0001F4A9"));
|
||||
}
|
||||
|
||||
bool u16string_is_utf16();
|
||||
bool u16string_is_utf16()
|
||||
{
|
||||
return (std::u16string(u"💩") == std::u16string(u"\U0001F4A9"));
|
||||
}
|
||||
|
||||
bool u32string_is_utf32();
|
||||
bool u32string_is_utf32()
|
||||
{
|
||||
return (std::u32string(U"💩") == std::u32string(U"\U0001F4A9"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("wide strings")
|
||||
{
|
||||
SECTION("std::wstring")
|
||||
{
|
||||
if (wstring_is_utf16())
|
||||
{
|
||||
std::wstring w = L"[12.2,\"Ⴥaäö💤🧢\"]";
|
||||
json j = json::parse(w);
|
||||
CHECK(j.dump() == "[12.2,\"Ⴥaäö💤🧢\"]");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("invalid std::wstring")
|
||||
{
|
||||
if (wstring_is_utf16())
|
||||
{
|
||||
std::wstring w = L"\"\xDBFF";
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::parse(w), json::parse_error&);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("std::u16string")
|
||||
{
|
||||
if (u16string_is_utf16())
|
||||
{
|
||||
std::u16string w = u"[12.2,\"Ⴥaäö💤🧢\"]";
|
||||
json j = json::parse(w);
|
||||
CHECK(j.dump() == "[12.2,\"Ⴥaäö💤🧢\"]");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("invalid std::u16string")
|
||||
{
|
||||
if (wstring_is_utf16())
|
||||
{
|
||||
std::u16string w = u"\"\xDBFF";
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::parse(w), json::parse_error&);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("std::u32string")
|
||||
{
|
||||
if (u32string_is_utf32())
|
||||
{
|
||||
std::u32string w = U"[12.2,\"Ⴥaäö💤🧢\"]";
|
||||
json j = json::parse(w);
|
||||
CHECK(j.dump() == "[12.2,\"Ⴥaäö💤🧢\"]");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("invalid std::u32string")
|
||||
{
|
||||
if (u32string_is_utf32())
|
||||
{
|
||||
std::u32string w = U"\"\x110000";
|
||||
json _;
|
||||
CHECK_THROWS_AS(_ = json::parse(w), json::parse_error&);
|
||||
}
|
||||
}
|
||||
}
|
||||
31
vendor/json/test/src/unit.cpp
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 3.9.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
|
||||
#include "doctest_compatibility.h"
|
||||
45
vendor/json/test/thirdparty/Fuzzer/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
set(LIBFUZZER_FLAGS_BASE "${CMAKE_CXX_FLAGS}")
|
||||
# Disable the coverage and sanitizer instrumentation for the fuzzer itself.
|
||||
set(CMAKE_CXX_FLAGS "${LIBFUZZER_FLAGS_BASE} -fno-sanitize-coverage=trace-pc-guard,edge,trace-cmp,indirect-calls,8bit-counters -Werror")
|
||||
if( LLVM_USE_SANITIZE_COVERAGE )
|
||||
if(NOT "${LLVM_USE_SANITIZER}" STREQUAL "Address")
|
||||
message(FATAL_ERROR
|
||||
"LibFuzzer and its tests require LLVM_USE_SANITIZER=Address and "
|
||||
"LLVM_USE_SANITIZE_COVERAGE=YES to be set."
|
||||
)
|
||||
endif()
|
||||
add_library(LLVMFuzzerNoMainObjects OBJECT
|
||||
FuzzerCrossOver.cpp
|
||||
FuzzerDriver.cpp
|
||||
FuzzerExtFunctionsDlsym.cpp
|
||||
FuzzerExtFunctionsWeak.cpp
|
||||
FuzzerExtFunctionsWeakAlias.cpp
|
||||
FuzzerIO.cpp
|
||||
FuzzerIOPosix.cpp
|
||||
FuzzerIOWindows.cpp
|
||||
FuzzerLoop.cpp
|
||||
FuzzerMerge.cpp
|
||||
FuzzerMutate.cpp
|
||||
FuzzerSHA1.cpp
|
||||
FuzzerTracePC.cpp
|
||||
FuzzerTraceState.cpp
|
||||
FuzzerUtil.cpp
|
||||
FuzzerUtilDarwin.cpp
|
||||
FuzzerUtilLinux.cpp
|
||||
FuzzerUtilPosix.cpp
|
||||
FuzzerUtilWindows.cpp
|
||||
)
|
||||
add_library(LLVMFuzzerNoMain STATIC
|
||||
$<TARGET_OBJECTS:LLVMFuzzerNoMainObjects>
|
||||
)
|
||||
target_link_libraries(LLVMFuzzerNoMain ${PTHREAD_LIB})
|
||||
add_library(LLVMFuzzer STATIC
|
||||
FuzzerMain.cpp
|
||||
$<TARGET_OBJECTS:LLVMFuzzerNoMainObjects>
|
||||
)
|
||||
target_link_libraries(LLVMFuzzer ${PTHREAD_LIB})
|
||||
|
||||
if( LLVM_INCLUDE_TESTS )
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
endif()
|
||||
217
vendor/json/test/thirdparty/Fuzzer/FuzzerCorpus.h
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
//===- FuzzerCorpus.h - Internal header for the Fuzzer ----------*- C++ -* ===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
// fuzzer::InputCorpus
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_FUZZER_CORPUS
|
||||
#define LLVM_FUZZER_CORPUS
|
||||
|
||||
#include "FuzzerDefs.h"
|
||||
#include "FuzzerIO.h"
|
||||
#include "FuzzerRandom.h"
|
||||
#include "FuzzerSHA1.h"
|
||||
#include "FuzzerTracePC.h"
|
||||
#include <numeric>
|
||||
#include <random>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace fuzzer {
|
||||
|
||||
struct InputInfo {
|
||||
Unit U; // The actual input data.
|
||||
uint8_t Sha1[kSHA1NumBytes]; // Checksum.
|
||||
// Number of features that this input has and no smaller input has.
|
||||
size_t NumFeatures = 0;
|
||||
size_t Tmp = 0; // Used by ValidateFeatureSet.
|
||||
// Stats.
|
||||
size_t NumExecutedMutations = 0;
|
||||
size_t NumSuccessfullMutations = 0;
|
||||
bool MayDeleteFile = false;
|
||||
};
|
||||
|
||||
class InputCorpus {
|
||||
public:
|
||||
static const size_t kFeatureSetSize = 1 << 16;
|
||||
InputCorpus(const std::string &OutputCorpus) : OutputCorpus(OutputCorpus) {
|
||||
memset(InputSizesPerFeature, 0, sizeof(InputSizesPerFeature));
|
||||
memset(SmallestElementPerFeature, 0, sizeof(SmallestElementPerFeature));
|
||||
}
|
||||
~InputCorpus() {
|
||||
for (auto II : Inputs)
|
||||
delete II;
|
||||
}
|
||||
size_t size() const { return Inputs.size(); }
|
||||
size_t SizeInBytes() const {
|
||||
size_t Res = 0;
|
||||
for (auto II : Inputs)
|
||||
Res += II->U.size();
|
||||
return Res;
|
||||
}
|
||||
size_t NumActiveUnits() const {
|
||||
size_t Res = 0;
|
||||
for (auto II : Inputs)
|
||||
Res += !II->U.empty();
|
||||
return Res;
|
||||
}
|
||||
bool empty() const { return Inputs.empty(); }
|
||||
const Unit &operator[] (size_t Idx) const { return Inputs[Idx]->U; }
|
||||
void AddToCorpus(const Unit &U, size_t NumFeatures, bool MayDeleteFile = false) {
|
||||
assert(!U.empty());
|
||||
uint8_t Hash[kSHA1NumBytes];
|
||||
if (FeatureDebug)
|
||||
Printf("ADD_TO_CORPUS %zd NF %zd\n", Inputs.size(), NumFeatures);
|
||||
ComputeSHA1(U.data(), U.size(), Hash);
|
||||
Hashes.insert(Sha1ToString(Hash));
|
||||
Inputs.push_back(new InputInfo());
|
||||
InputInfo &II = *Inputs.back();
|
||||
II.U = U;
|
||||
II.NumFeatures = NumFeatures;
|
||||
II.MayDeleteFile = MayDeleteFile;
|
||||
memcpy(II.Sha1, Hash, kSHA1NumBytes);
|
||||
UpdateCorpusDistribution();
|
||||
ValidateFeatureSet();
|
||||
}
|
||||
|
||||
bool HasUnit(const Unit &U) { return Hashes.count(Hash(U)); }
|
||||
bool HasUnit(const std::string &H) { return Hashes.count(H); }
|
||||
InputInfo &ChooseUnitToMutate(Random &Rand) {
|
||||
InputInfo &II = *Inputs[ChooseUnitIdxToMutate(Rand)];
|
||||
assert(!II.U.empty());
|
||||
return II;
|
||||
};
|
||||
|
||||
// Returns an index of random unit from the corpus to mutate.
|
||||
// Hypothesis: units added to the corpus last are more likely to be
|
||||
// interesting. This function gives more weight to the more recent units.
|
||||
size_t ChooseUnitIdxToMutate(Random &Rand) {
|
||||
size_t Idx = static_cast<size_t>(CorpusDistribution(Rand.Get_mt19937()));
|
||||
assert(Idx < Inputs.size());
|
||||
return Idx;
|
||||
}
|
||||
|
||||
void PrintStats() {
|
||||
for (size_t i = 0; i < Inputs.size(); i++) {
|
||||
const auto &II = *Inputs[i];
|
||||
Printf(" [%zd %s]\tsz: %zd\truns: %zd\tsucc: %zd\n", i,
|
||||
Sha1ToString(II.Sha1).c_str(), II.U.size(),
|
||||
II.NumExecutedMutations, II.NumSuccessfullMutations);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintFeatureSet() {
|
||||
for (size_t i = 0; i < kFeatureSetSize; i++) {
|
||||
if(size_t Sz = GetFeature(i))
|
||||
Printf("[%zd: id %zd sz%zd] ", i, SmallestElementPerFeature[i], Sz);
|
||||
}
|
||||
Printf("\n\t");
|
||||
for (size_t i = 0; i < Inputs.size(); i++)
|
||||
if (size_t N = Inputs[i]->NumFeatures)
|
||||
Printf(" %zd=>%zd ", i, N);
|
||||
Printf("\n");
|
||||
}
|
||||
|
||||
void DeleteInput(size_t Idx) {
|
||||
InputInfo &II = *Inputs[Idx];
|
||||
if (!OutputCorpus.empty() && II.MayDeleteFile)
|
||||
RemoveFile(DirPlusFile(OutputCorpus, Sha1ToString(II.Sha1)));
|
||||
Unit().swap(II.U);
|
||||
if (FeatureDebug)
|
||||
Printf("EVICTED %zd\n", Idx);
|
||||
}
|
||||
|
||||
bool AddFeature(size_t Idx, uint32_t NewSize, bool Shrink) {
|
||||
assert(NewSize);
|
||||
Idx = Idx % kFeatureSetSize;
|
||||
uint32_t OldSize = GetFeature(Idx);
|
||||
if (OldSize == 0 || (Shrink && OldSize > NewSize)) {
|
||||
if (OldSize > 0) {
|
||||
size_t OldIdx = SmallestElementPerFeature[Idx];
|
||||
InputInfo &II = *Inputs[OldIdx];
|
||||
assert(II.NumFeatures > 0);
|
||||
II.NumFeatures--;
|
||||
if (II.NumFeatures == 0)
|
||||
DeleteInput(OldIdx);
|
||||
}
|
||||
if (FeatureDebug)
|
||||
Printf("ADD FEATURE %zd sz %d\n", Idx, NewSize);
|
||||
SmallestElementPerFeature[Idx] = Inputs.size();
|
||||
InputSizesPerFeature[Idx] = NewSize;
|
||||
CountingFeatures = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t NumFeatures() const {
|
||||
size_t Res = 0;
|
||||
for (size_t i = 0; i < kFeatureSetSize; i++)
|
||||
Res += GetFeature(i) != 0;
|
||||
return Res;
|
||||
}
|
||||
|
||||
void ResetFeatureSet() {
|
||||
assert(Inputs.empty());
|
||||
memset(InputSizesPerFeature, 0, sizeof(InputSizesPerFeature));
|
||||
memset(SmallestElementPerFeature, 0, sizeof(SmallestElementPerFeature));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static const bool FeatureDebug = false;
|
||||
|
||||
size_t GetFeature(size_t Idx) const { return InputSizesPerFeature[Idx]; }
|
||||
|
||||
void ValidateFeatureSet() {
|
||||
if (!CountingFeatures) return;
|
||||
if (FeatureDebug)
|
||||
PrintFeatureSet();
|
||||
for (size_t Idx = 0; Idx < kFeatureSetSize; Idx++)
|
||||
if (GetFeature(Idx))
|
||||
Inputs[SmallestElementPerFeature[Idx]]->Tmp++;
|
||||
for (auto II: Inputs) {
|
||||
if (II->Tmp != II->NumFeatures)
|
||||
Printf("ZZZ %zd %zd\n", II->Tmp, II->NumFeatures);
|
||||
assert(II->Tmp == II->NumFeatures);
|
||||
II->Tmp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the probability distribution for the units in the corpus.
|
||||
// Must be called whenever the corpus or unit weights are changed.
|
||||
void UpdateCorpusDistribution() {
|
||||
size_t N = Inputs.size();
|
||||
Intervals.resize(N + 1);
|
||||
Weights.resize(N);
|
||||
std::iota(Intervals.begin(), Intervals.end(), 0);
|
||||
if (CountingFeatures)
|
||||
for (size_t i = 0; i < N; i++)
|
||||
Weights[i] = Inputs[i]->NumFeatures * (i + 1);
|
||||
else
|
||||
std::iota(Weights.begin(), Weights.end(), 1);
|
||||
CorpusDistribution = std::piecewise_constant_distribution<double>(
|
||||
Intervals.begin(), Intervals.end(), Weights.begin());
|
||||
}
|
||||
std::piecewise_constant_distribution<double> CorpusDistribution;
|
||||
|
||||
std::vector<double> Intervals;
|
||||
std::vector<double> Weights;
|
||||
|
||||
std::unordered_set<std::string> Hashes;
|
||||
std::vector<InputInfo*> Inputs;
|
||||
|
||||
bool CountingFeatures = false;
|
||||
uint32_t InputSizesPerFeature[kFeatureSetSize];
|
||||
uint32_t SmallestElementPerFeature[kFeatureSetSize];
|
||||
|
||||
std::string OutputCorpus;
|
||||
};
|
||||
|
||||
} // namespace fuzzer
|
||||
|
||||
#endif // LLVM_FUZZER_CORPUS
|
||||