# TODO clean this up, but for now it makes tests get appropriate options

cmake_policy( SET CMP0065 NEW )

set( CMAKE_CXX_STANDARD_REQUIRED ON )
if( CYGWIN )
	set( CMAKE_CXX_EXTENSIONS ON )
else()
	set( CMAKE_CXX_EXTENSIONS OFF )
endif()

find_package( Boost 1.83.0 COMPONENTS container system )
find_package( Threads )

option( DAW_JSON_USE_REFLECTION "Enable testing of reflection p2996 for JSON" OFF )
if( DAW_JSON_USE_REFLECTION )
	message( STATUS "DAW_JSON_USE_REFLECTION=ON: Enabled testing of reflection p2996 for JSON" )
	add_compile_definitions( DAW_JSON_USE_REFLECTION )
endif()

if( ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" )
	if( CLANG_VERSION_MAJOR VERSION_LESS 13 )
		# Constexpr causes some ICE'ing on clang prior to v11
		option( DAW_JSON_NO_CONST_EXPR "Define: Ensure guaranteed copy elision in array/class types" ON )
	else()
		option( DAW_JSON_NO_CONST_EXPR "Define: Ensure guaranteed copy elision in array/class types" OFF )
	endif()
else()
	option( DAW_JSON_NO_CONST_EXPR "Define: Ensure guaranteed copy elision in array/class types" OFF )
endif()

set( DAW_NUM_RUNS OFF CACHE STRING "Define: Change the number of runs of some tests" )
option( CMAKE_INTERPROCEDURAL_OPTIMIZATION "Enable LTO" OFF )
option( DAW_JSON_USE_SANITIZERS "Enable address and undefined behaviour sanitizers" OFF )
option( DAW_JSON_FULL_TESTS "Enable tests for benchmarks" OFF )
option( DAW_JSON_NO_INT128 "Disable 128bit int tests" OFF )

if( DAW_JSON_NO_CONST_EXPR )
	message( STATUS "DAW_JSON_NO_CONST_EXPR=ON: Guaranteed copy elision in class/array types is ON" )
	add_definitions( -DDAW_JSON_NO_CONST_EXPR )
else()
	message( STATUS "DAW_JSON_NO_CONST_EXPR=OFF: Guaranteed copy elision in class/array types is OFF" )
endif()

if( CMAKE_INTERPROCEDURAL_OPTIMIZATION )
	message( STATUS "CMAKE_INTERPROCEDURAL_OPTIMIZATION=ON: LTO is enabled" )
endif()
message( STATUS "CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}" )

if( DAW_NUM_RUNS )
	message( STATUS "DAW_NUM_RUNS=${DAW_NUM_RUNS}: Overriding number of test runs" )
	add_definitions( -DDAW_NUM_RUNS=${DAW_NUM_RUNS} )
endif()

if( DAW_JSON_USE_SANITIZERS )
	message( STATUS "DAW_JSON_USE_SANITIZERS=ON: compiler sanitizers enabled" )
	add_definitions( -DDAW_JSON_NO_INT128 )
else()
	message( STATUS "DAW_JSON_USE_SANITIZERS=OFF: compiler sanitizers disabled" )
endif()

if( DAW_JSON_NO_INT128 )
	message( STATUS "DAW_JSON_NO_INT128=ON: int128 tests are disabled" )
	add_definitions( -DDAW_JSON_NO_INT128 )
endif()

include( cmake/test_compiler_options.cmake )
add_subdirectory( extern )

add_library( json_test INTERFACE )

if( DAW_USE_PACKAGE_MANAGEMENT )
	target_link_libraries( json_test INTERFACE ${COMPILER_SPECIFIC_LIBS} )
else()
	target_link_libraries( json_test INTERFACE daw::daw-json-link daw::daw-header-libraries daw::daw-utf-range ${COMPILER_SPECIFIC_LIBS} )
endif()

target_include_directories( json_test INTERFACE include/ )

add_custom_target( full )
add_custom_target( ci_tests )

if( ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" )
	if( CLANG_VERSION_MAJOR VERSION_GREATER 11 )
		set( DAW_JSON_LINK_TEST_ALWAYS )
	endif()
endif()
if( DAW_JSON_FULL_TESTS OR DAW_JSON_LINK_TEST_ALWAYS )
	add_executable( daw_json_link_test src/daw_json_link_test.cpp )
	add_test( NAME daw_json_link_test COMMAND daw_json_link_test )
	add_dependencies( ci_tests daw_json_link_test )
else()
	add_executable( daw_json_link_test EXCLUDE_FROM_ALL src/daw_json_link_test.cpp )
endif()
target_link_libraries( daw_json_link_test PRIVATE json_test )
add_dependencies( full daw_json_link_test )

if( DAW_JSON_FULL_TESTS )
	add_executable( city_test src/city_test.cpp )
	add_test( NAME city_test COMMAND city_test ./cities.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
else()
	add_executable( city_test EXCLUDE_FROM_ALL src/city_test.cpp )
endif()
target_link_libraries( city_test PRIVATE json_test )
add_dependencies( full city_test )

if( DAW_JSON_FULL_TESTS )
	add_executable( int_array_test src/int_array_test.cpp )
	add_test( NAME int_array_test COMMAND int_array_test )
else()
	add_executable( int_array_test EXCLUDE_FROM_ALL src/int_array_test.cpp )
endif()
target_link_libraries( int_array_test PRIVATE json_test )
add_dependencies( full int_array_test )

add_executable( int_array_basic_test src/int_array_basic_test.cpp )
target_link_libraries( int_array_basic_test PRIVATE json_test )
add_test( NAME int_array_basic_test COMMAND int_array_basic_test )
add_dependencies( ci_tests int_array_basic_test )
add_dependencies( full int_array_basic_test )

add_executable( float_array_test src/float_array_test.cpp )
target_link_libraries( float_array_test PRIVATE json_test )
add_test( NAME float_array_test COMMAND float_array_test )
add_dependencies( ci_tests float_array_test )
add_dependencies( full float_array_test )

add_executable( simple_test src/simple_test.cpp )
target_link_libraries( simple_test PRIVATE json_test )
add_test( NAME simple_test COMMAND simple_test ./cities.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests simple_test )
add_dependencies( full simple_test )

add_executable( coords_test src/coords_test.cpp )
target_link_libraries( coords_test PRIVATE json_test )
#add_test( NAME coords_test COMMAND coords_test)
add_dependencies( full coords_test )

if( NOT DEFINED MSVC )
	add_executable( kostya_bench src/kostya_bench.cpp )
	target_link_libraries( kostya_bench PRIVATE json_test )
	#add_test( NAME kostya_bench COMMAND kostya_bench)
	add_dependencies( full kostya_bench )

	add_executable( kostya_bench2 src/kostya_bench2.cpp )
	target_link_libraries( kostya_bench2 PRIVATE json_test )
	#add_test( NAME kostya_bench2 COMMAND kostya_bench2)
	add_dependencies( full kostya_bench2 )

	add_executable( kostya_bench3 src/kostya_bench3.cpp )
	target_link_libraries( kostya_bench3 PRIVATE json_test )
	#add_test( NAME kostya_bench3 COMMAND kostya_bench3)
	add_dependencies( full kostya_bench3 )
endif()

add_executable( coords_test2 src/coords_test2.cpp )
target_link_libraries( coords_test2 PRIVATE json_test )
#add_test( NAME coords_test2 COMMAND coords_test2)
add_dependencies( full coords_test2 )

if( DAW_JSON_FULL_TESTS )
	add_executable( nativejson_bench src/nativejson_bench.cpp )
	add_test( NAME nativejson_bench COMMAND nativejson_bench ./twitter.json ./citm_catalog.json ./canada.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
else()
	add_executable( nativejson_bench EXCLUDE_FROM_ALL src/nativejson_bench.cpp )
endif()
target_link_libraries( nativejson_bench PRIVATE json_test )
add_dependencies( full nativejson_bench )

add_executable( nativejson_bench_alloc EXCLUDE_FROM_ALL src/nativejson_bench_alloc.cpp )
target_link_libraries( nativejson_bench_alloc PRIVATE json_test )
add_dependencies( full nativejson_bench_alloc )

if( DAW_JSON_FULL_TESTS )
	add_executable( nativejson_bench2 src/nativejson_bench2.cpp )
	add_test( NAME nativejson_bench2 COMMAND nativejson_bench2 ./twitter.json ./citm_catalog.json ./canada.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
else()
	add_executable( nativejson_bench2 EXCLUDE_FROM_ALL src/nativejson_bench2.cpp )
endif()
target_link_libraries( nativejson_bench2 PRIVATE json_test )
add_dependencies( full nativejson_bench2 )

if( DAW_JSON_FULL_TESTS )
	add_executable( nativejson_bench_basic src/nativejson_bench_basic.cpp )
	add_test( NAME nativejson_bench_basic COMMAND nativejson_bench_basic ./twitter.json ./citm_catalog.json ./canada.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
else()
	add_executable( nativejson_bench_basic EXCLUDE_FROM_ALL src/nativejson_bench_basic.cpp )
endif()
target_link_libraries( nativejson_bench_basic PRIVATE json_test )
add_dependencies( full nativejson_bench_basic )

if( DAW_JSON_FULL_TESTS )
	add_executable( nativejson_bench_basic2 src/nativejson_bench_basic2.cpp )
	add_test( NAME nativejson_bench_basic2 COMMAND nativejson_bench_basic2 ./twitter.json ./citm_catalog.json ./canada.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
else()
	add_executable( nativejson_bench_basic2 EXCLUDE_FROM_ALL src/nativejson_bench_basic2.cpp )
endif()
target_link_libraries( nativejson_bench_basic2 PRIVATE json_test )
add_dependencies( full nativejson_bench_basic2 )

if( DAW_JSON_FULL_TESTS )
	add_executable( citm_test src/citm_test.cpp )
	add_test( NAME citm_test COMMAND citm_test ./citm_catalog.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
else()
	add_executable( citm_test EXCLUDE_FROM_ALL src/citm_test.cpp )
endif()
target_link_libraries( citm_test PRIVATE json_test )
add_dependencies( full citm_test )

add_executable( citm_test_alloc EXCLUDE_FROM_ALL src/citm_test_alloc.cpp )
target_link_libraries( citm_test_alloc PRIVATE json_test )
add_dependencies( full citm_test_alloc )

add_executable( citm_test_basic src/citm_test_basic.cpp )
target_link_libraries( citm_test_basic PRIVATE json_test )
add_test( NAME citm_test_basic COMMAND citm_test_basic ./citm_catalog.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests citm_test_basic )
add_dependencies( full citm_test_basic )

if( DAW_JSON_FULL_TESTS )
	add_executable( twitter_test src/twitter_test.cpp )
	add_test( NAME twitter_test COMMAND twitter_test ./twitter.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
else()
	add_executable( twitter_test EXCLUDE_FROM_ALL src/twitter_test.cpp )
endif()
target_link_libraries( twitter_test PRIVATE json_test )
add_dependencies( full twitter_test )


if( ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" AND CLANG_VERSION_MAJOR VERSION_GREATER_EQUAL 9 )
	if( DAW_JSON_FULL_TESTS )
		add_executable( twitter_output_test src/twitter_output_test.cpp )
		add_test( NAME twitter_output_test COMMAND twitter_output_test ./twitter.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
	else()
		add_executable( twitter_output_test EXCLUDE_FROM_ALL src/twitter_output_test.cpp )
	endif()
	target_link_libraries( twitter_output_test PRIVATE json_test )
	add_dependencies( full twitter_output_test )
endif()

add_executable( twitter_test_alloc EXCLUDE_FROM_ALL src/twitter_test_alloc.cpp )
target_link_libraries( twitter_test_alloc PRIVATE json_test )
add_dependencies( full twitter_test_alloc )

if( Boost_FOUND )
	add_executable( twitter_test_pmr EXCLUDE_FROM_ALL src/twitter_test_pmr.cpp )
	target_link_libraries( twitter_test_pmr PRIVATE json_test Boost::headers Boost::container )
	add_dependencies( full twitter_test_pmr )

	add_executable( daw_json_link_describe_bin src/daw_json_link_describe_test.cpp )
	target_link_libraries( daw_json_link_describe_bin PRIVATE json_test Boost::headers )
	target_compile_features( daw_json_link_describe_bin PRIVATE cxx_std_20 )
	add_test( NAME daw_json_link_describe_test COMMAND daw_json_link_describe_bin )
endif()

if( DAW_JSON_FULL_TESTS )
	add_executable( twitter_test2 src/twitter_test2.cpp )
	add_test( NAME twitter_test2 COMMAND twitter_test2 ./twitter.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
else()
	add_executable( twitter_test2 EXCLUDE_FROM_ALL src/twitter_test2.cpp )
endif()
target_link_libraries( twitter_test2 PRIVATE json_test )
add_dependencies( full twitter_test2 )

if( DAW_JSON_FULL_TESTS )
	add_executable( twitter_test_basic src/twitter_test_basic.cpp )
	add_test( NAME twitter_test_basic COMMAND twitter_test_basic ./twitter.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
else()
	add_executable( twitter_test_basic EXCLUDE_FROM_ALL src/twitter_test_basic.cpp )
endif()
target_link_libraries( twitter_test_basic PRIVATE json_test )
add_dependencies( full twitter_test_basic )

if( DAW_JSON_FULL_TESTS )
	add_executable( twitter_test_basic2 src/twitter_test_basic2.cpp )
	add_test( NAME twitter_test_basic2 COMMAND twitter_test_basic2 ./twitter.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
else()
	add_executable( twitter_test_basic2 EXCLUDE_FROM_ALL src/twitter_test_basic2.cpp )
endif()
target_link_libraries( twitter_test_basic2 PRIVATE json_test )
add_dependencies( full twitter_test_basic2 )

add_executable( twitter_timeline_test src/twitter_timeline_test.cpp )
target_link_libraries( twitter_timeline_test PRIVATE json_test )
add_test( NAME twitter_timeline_test COMMAND twitter_timeline_test ./twitter_timeline.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests twitter_timeline_test )
add_dependencies( full twitter_timeline_test )

add_executable( find_tweet_test src/find_tweet_test.cpp )
target_link_libraries( find_tweet_test PRIVATE json_test )
add_test( NAME find_tweet_test COMMAND find_tweet_test ./find_tweet.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests find_tweet_test )
add_dependencies( full find_tweet_test )

add_executable( amazon_cellphones_test src/amazon_cellphones_test.cpp )
target_link_libraries( amazon_cellphones_test PRIVATE json_test )
add_test( NAME amazon_cellphones_test COMMAND amazon_cellphones_test ./amazon_cellphones.ndjson WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests amazon_cellphones_test )
add_dependencies( full amazon_cellphones_test )

if( DAW_JSON_FULL_TESTS )
	add_executable( canada_test src/canada_test.cpp )
	add_test( NAME canada_test COMMAND canada_test ./canada.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
else()
	add_executable( canada_test EXCLUDE_FROM_ALL src/canada_test.cpp )
endif()
target_link_libraries( canada_test PRIVATE json_test )
add_dependencies( full canada_test )

if( DAW_JSON_FULL_TESTS )
	add_executable( canada_output_test src/canada_output_test.cpp )
	add_test( NAME canada_output_test COMMAND canada_output_test ./canada.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
else()
	add_executable( canada_output_test EXCLUDE_FROM_ALL src/canada_output_test.cpp )
endif()
target_link_libraries( canada_output_test PRIVATE json_test )
add_dependencies( full canada_output_test )

add_executable( canada_test_alloc EXCLUDE_FROM_ALL src/canada_test_alloc.cpp )
target_link_libraries( canada_test_alloc PRIVATE json_test )
add_dependencies( full canada_test_alloc )

add_executable( canada_test_basic src/canada_test_basic.cpp )
target_link_libraries( canada_test_basic PRIVATE json_test )
add_test( NAME canada_test_basic COMMAND canada_test_basic ./canada.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests canada_test_basic )
add_dependencies( full canada_test_basic )

add_executable( kv_map_test src/kv_map_test.cpp )
target_link_libraries( kv_map_test PRIVATE json_test )
add_test( NAME kv_map_test COMMAND kv_map_test )
add_dependencies( ci_tests kv_map_test )
add_dependencies( full kv_map_test )

add_executable( cookbook_kv1_test src/cookbook_kv1_test.cpp )
target_link_libraries( cookbook_kv1_test PRIVATE json_test )
add_test( NAME cookbook_kv1_test COMMAND cookbook_kv1_test ./cookbook_kv1.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_kv1_test )
add_dependencies( full cookbook_kv1_test )

add_executable( cookbook_kv2_test src/cookbook_kv2_test.cpp )
target_link_libraries( cookbook_kv2_test PRIVATE json_test )
add_test( NAME cookbook_kv2_test COMMAND cookbook_kv2_test ./cookbook_kv2.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_kv2_test )
add_dependencies( full cookbook_kv2_test )

add_executable( cookbook_kv3_test src/cookbook_kv3_test.cpp )
target_link_libraries( cookbook_kv3_test PRIVATE json_test )
add_test( NAME cookbook_kv3_test COMMAND cookbook_kv3_test ./cookbook_kv3.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_kv3_test )
add_dependencies( full cookbook_kv3_test )

add_executable( cookbook_kv4_test src/cookbook_kv4_test.cpp )
target_link_libraries( cookbook_kv4_test PRIVATE json_test )
add_test( NAME cookbook_kv4_test COMMAND cookbook_kv4_test ./cookbook_kv4.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_kv4_test )
add_dependencies( full cookbook_kv4_test )

add_executable( cookbook_class1_test src/cookbook_class1_test.cpp )
target_link_libraries( cookbook_class1_test PRIVATE json_test )
add_test( NAME cookbook_class1_test COMMAND cookbook_class1_test ./cookbook_class1.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_class1_test )
add_dependencies( full cookbook_class1_test )

add_executable( cookbook_class2_test src/cookbook_class2_test.cpp )
target_link_libraries( cookbook_class2_test PRIVATE json_test )
add_test( NAME cookbook_class2_test COMMAND cookbook_class2_test ./cookbook_class2.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_class2_test )
add_dependencies( full cookbook_class2_test )

add_executable( cookbook_class3_test src/cookbook_class3_test.cpp )
target_link_libraries( cookbook_class3_test PRIVATE json_test )
add_test( NAME cookbook_class3_test COMMAND cookbook_class3_test ./cookbook_class3.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_class3_test )
add_dependencies( full cookbook_class3_test )

add_executable( cookbook_array1_test src/cookbook_array1_test.cpp )
target_link_libraries( cookbook_array1_test PRIVATE json_test )
add_test( NAME cookbook_array1_test COMMAND cookbook_array1_test ./cookbook_array1.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_array1_test )
add_dependencies( full cookbook_array1_test )

add_executable( cookbook_array2_test src/cookbook_array2_test.cpp )
target_link_libraries( cookbook_array2_test PRIVATE json_test )
add_test( NAME cookbook_array2_test COMMAND cookbook_array2_test ./cookbook_array2.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_array2_test )
add_dependencies( full cookbook_array2_test )

add_executable( cookbook_array3_test src/cookbook_array3_test.cpp )
target_link_libraries( cookbook_array3_test PRIVATE json_test )
add_test( NAME cookbook_array3_test COMMAND cookbook_array3_test ./cookbook_array3.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_array3_test )
add_dependencies( full cookbook_array3_test )

add_executable( cookbook_escaped_strings1_test src/cookbook_escaped_strings1_test.cpp )
target_link_libraries( cookbook_escaped_strings1_test PRIVATE json_test )
add_test( NAME cookbook_escaped_strings1_test COMMAND cookbook_escaped_strings1_test ./cookbook_escaped_strings1.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_escaped_strings1_test )
add_dependencies( full cookbook_escaped_strings1_test )

add_executable( full_unicode_roundtrip_test src/full_unicode_roundtrip_test.cpp )
target_link_libraries( full_unicode_roundtrip_test PRIVATE json_test )
add_test( NAME full_unicode_roundtrip_test COMMAND full_unicode_roundtrip_test ./full_unicode.json ./full_unicode_escaped.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests full_unicode_roundtrip_test )
add_dependencies( full full_unicode_roundtrip_test )

add_executable( make_full24 src/make_full24.cpp )
target_link_libraries( make_full24 PRIVATE json_test )
add_dependencies( full make_full24 )

add_executable( cookbook_enums1_test src/cookbook_enums1_test.cpp )
target_link_libraries( cookbook_enums1_test PRIVATE json_test )
add_test( NAME cookbook_enums1_test COMMAND cookbook_enums1_test ./cookbook_enums1.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_enums1_test )
add_dependencies( full cookbook_enums1_test )

add_executable( cookbook_enums2_test src/cookbook_enums2_test.cpp )
target_link_libraries( cookbook_enums2_test PRIVATE json_test )
add_test( NAME cookbook_enums2_test COMMAND cookbook_enums2_test ./cookbook_enums2.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_enums2_test )
add_dependencies( full cookbook_enums2_test )

add_executable( cookbook_graphs1_test src/cookbook_graphs1_test.cpp )
target_link_libraries( cookbook_graphs1_test PRIVATE json_test )
add_test( NAME cookbook_graphs1_test COMMAND cookbook_graphs1_test ./cookbook_graphs1.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_graphs1_test )
add_dependencies( full cookbook_graphs1_test )

add_executable( cookbook_optional_values1_test src/cookbook_optional_values1_test.cpp )
target_link_libraries( cookbook_optional_values1_test PRIVATE json_test )
add_test( NAME cookbook_optional_values1_test COMMAND cookbook_optional_values1_test ./cookbook_optional_values1.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_optional_values1_test )
add_dependencies( full cookbook_optional_values1_test )

add_executable( cookbook_variant1_test src/cookbook_variant1_test.cpp )
target_link_libraries( cookbook_variant1_test PRIVATE json_test )
add_test( NAME cookbook_variant1_test COMMAND cookbook_variant1_test ./cookbook_variant1.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_variant1_test )
add_dependencies( full cookbook_variant1_test )

add_executable( small_test src/small_test.cpp )
target_link_libraries( small_test PRIVATE json_test )
add_test( NAME small_test COMMAND small_test ./small_test.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests small_test )
add_dependencies( full small_test )

if( DAW_USE_EXCEPTIONS )
	add_executable( should_fail src/should_fail_001.cpp )
	target_link_libraries( should_fail PRIVATE json_test )
	add_test( should_fail should_fail )
	add_dependencies( ci_tests should_fail )
	add_dependencies( full should_fail )
endif()

add_executable( trailing_commas src/trailing_commas.cpp )
target_link_libraries( trailing_commas PRIVATE json_test )
add_test( trailing_commas_test trailing_commas )
add_dependencies( ci_tests trailing_commas )
add_dependencies( full trailing_commas )

add_executable( cookbook_parsing_individual_members1_test src/cookbook_parsing_individual_members1_test.cpp )
target_link_libraries( cookbook_parsing_individual_members1_test PRIVATE json_test )
add_test( NAME cookbook_parsing_individual_members1_test COMMAND cookbook_parsing_individual_members1_test ./cookbook_parsing_individual_members1.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_parsing_individual_members1_test )
add_dependencies( full cookbook_parsing_individual_members1_test )

add_executable( cookbook_parsing_individual_members2_test src/cookbook_parsing_individual_members2_test.cpp )
target_link_libraries( cookbook_parsing_individual_members2_test PRIVATE json_test )
add_test( NAME cookbook_parsing_individual_members2_test COMMAND cookbook_parsing_individual_members2_test ./cookbook_parsing_individual_members2.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_parsing_individual_members2_test )
add_dependencies( full cookbook_parsing_individual_members2_test )

add_executable( cookbook_parsing_individual_members3_test src/cookbook_parsing_individual_members3_test.cpp )
target_link_libraries( cookbook_parsing_individual_members3_test PRIVATE json_test )
add_test( NAME cookbook_parsing_individual_members3_test COMMAND cookbook_parsing_individual_members3_test ./cookbook_parsing_individual_members3.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_parsing_individual_members3_test )
add_dependencies( full cookbook_parsing_individual_members3_test )

add_executable( cookbook_variant2_test src/cookbook_variant2_test.cpp )
target_link_libraries( cookbook_variant2_test PRIVATE json_test )
add_test( NAME cookbook_variant2_test COMMAND cookbook_variant2_test ./cookbook_variant2.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_variant2_test )
add_dependencies( full cookbook_variant2_test )

add_executable( cookbook_variant3_test src/cookbook_variant3_test.cpp )
target_link_libraries( cookbook_variant3_test PRIVATE json_test )
add_test( NAME cookbook_variant3_test COMMAND cookbook_variant3_test ./cookbook_variant3.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_variant3_test )
add_dependencies( full cookbook_variant3_test )

add_executable( cookbook_variant4_test src/cookbook_variant4_test.cpp )
target_link_libraries( cookbook_variant4_test PRIVATE json_test )
add_test( NAME cookbook_variant4_test COMMAND cookbook_variant4_test ./cookbook_variant4.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_variant4_test )
add_dependencies( full cookbook_variant4_test )

if( DAW_JSON_FULL_TESTS )
	add_executable( cookbook_variant5_test src/cookbook_variant5_test.cpp )
	add_test( NAME cookbook_variant5_test COMMAND cookbook_variant5_test ./cookbook_variant5.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
else()
	add_executable( cookbook_variant5_test EXCLUDE_FROM_ALL src/cookbook_variant5_test.cpp )
endif()
target_link_libraries( cookbook_variant5_test PRIVATE json_test )
add_dependencies( ci_tests cookbook_variant5_test )
add_dependencies( full cookbook_variant5_test )

add_executable( optional_tagged_variant_test src/optional_tagged_variant_test.cpp )
target_link_libraries( optional_tagged_variant_test PRIVATE json_test )
add_test( NAME optional_tagged_variant_test COMMAND optional_tagged_variant_test ./optional_tagged_variant.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests optional_tagged_variant_test )
add_dependencies( full optional_tagged_variant_test )

add_executable( optional_variant_test src/optional_variant_test.cpp )
target_link_libraries( optional_variant_test PRIVATE json_test )
add_test( NAME optional_variant_test COMMAND optional_variant_test ./optional_variant.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests optional_variant_test )
add_dependencies( full optional_variant_test )

add_executable( daw_murmur3_test src/daw_murmur3_test.cpp )
target_link_libraries( daw_murmur3_test PRIVATE json_test )
add_test( NAME daw_murmur3_test COMMAND daw_murmur3_test )
add_dependencies( ci_tests daw_murmur3_test )
add_dependencies( full daw_murmur3_test )

if( DAW_JSON_FULL_TESTS )
	add_executable( apache_builds_test src/apache_builds_test.cpp )
	add_test( NAME apache_builds_test COMMAND apache_builds_test ./apache_builds.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
else()
	add_executable( apache_builds_test EXCLUDE_FROM_ALL src/apache_builds_test.cpp )
endif()
target_link_libraries( apache_builds_test PRIVATE json_test )
add_dependencies( full apache_builds_test )

add_executable( apache_builds_cpp_comments_test src/apache_builds_cpp_comments_test.cpp )
target_link_libraries( apache_builds_cpp_comments_test PRIVATE json_test )
add_test( NAME apache_builds_cpp_comments_test COMMAND apache_builds_cpp_comments_test ./apache_builds_cpp_comments.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests apache_builds_cpp_comments_test )
add_dependencies( full apache_builds_cpp_comments_test )

add_executable( apache_builds_hash_comments_test src/apache_builds_hash_comments_test.cpp )
target_link_libraries( apache_builds_hash_comments_test PRIVATE json_test )
add_test( NAME apache_builds_hash_comments_test COMMAND apache_builds_hash_comments_test ./apache_builds_hash_comments.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests apache_builds_hash_comments_test )
add_dependencies( full apache_builds_hash_comments_test )

add_executable( cookbook_dates1_test src/cookbook_dates1_test.cpp )
target_link_libraries( cookbook_dates1_test PRIVATE json_test )
add_test( NAME cookbook_dates1_test COMMAND cookbook_dates1_test ./cookbook_dates1.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_dates1_test )
add_dependencies( full cookbook_dates1_test )

add_executable( cookbook_dates2_test src/cookbook_dates2_test.cpp )
target_link_libraries( cookbook_dates2_test PRIVATE json_test )
add_test( NAME cookbook_dates2_test COMMAND cookbook_dates2_test ./cookbook_dates2.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_dates2_test )
add_dependencies( full cookbook_dates2_test )

add_executable( cookbook_dates3_test src/cookbook_dates3_test.cpp )
target_link_libraries( cookbook_dates3_test PRIVATE json_test )
add_test( NAME cookbook_dates3_test COMMAND cookbook_dates3_test ./cookbook_dates3.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_dates3_test )
add_dependencies( full cookbook_dates3_test )

add_executable( cookbook_dates4_test src/cookbook_dates4_test.cpp )
target_link_libraries( cookbook_dates4_test PRIVATE json_test )
add_test( NAME cookbook_dates4_test COMMAND cookbook_dates4_test ./cookbook_dates4.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_dates4_test )
add_dependencies( full cookbook_dates4_test )

# Cannot be used due to perf issue with uncaught_exceptions/MSVC's dtors that prevent this facility
if( NOT DEFINED MSVC )
	add_executable( no_move_or_copy_cls_test src/no_move_or_copy_cls_test.cpp )
	target_link_libraries( no_move_or_copy_cls_test PRIVATE json_test )
	add_test( NAME no_move_or_copy_cls_test COMMAND no_move_or_copy_cls_test )
	add_dependencies( ci_tests no_move_or_copy_cls_test )
	add_dependencies( full no_move_or_copy_cls_test )
endif()

add_executable( cookbook_class_from_array1_test src/cookbook_class_from_array1_test.cpp )
target_link_libraries( cookbook_class_from_array1_test PRIVATE json_test )
add_test( NAME cookbook_class_from_array1_test COMMAND cookbook_class_from_array1_test ./cookbook_class_from_array1.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_class_from_array1_test )
add_dependencies( full cookbook_class_from_array1_test )

add_executable( cookbook_class_from_array2_test src/cookbook_class_from_array2_test.cpp )
target_link_libraries( cookbook_class_from_array2_test PRIVATE json_test )
add_test( NAME cookbook_class_from_array2_test COMMAND cookbook_class_from_array2_test ./cookbook_class_from_array2.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_class_from_array2_test )
add_dependencies( full cookbook_class_from_array2_test )

add_executable( cookbook_numbers1_test src/cookbook_numbers1_test.cpp )
target_link_libraries( cookbook_numbers1_test PRIVATE json_test )
add_test( NAME cookbook_numbers1_test COMMAND cookbook_numbers1_test ./cookbook_numbers1.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_numbers1_test )
add_dependencies( full cookbook_numbers1_test )

add_executable( cookbook_numbers2_test src/cookbook_numbers2_test.cpp )
target_link_libraries( cookbook_numbers2_test PRIVATE json_test )
add_test( NAME cookbook_numbers2_test COMMAND cookbook_numbers2_test ./cookbook_numbers2.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_numbers2_test )
add_dependencies( full cookbook_numbers2_test )

if( Boost_FOUND AND DAW_USE_EXCEPTIONS )
	add_executable( cookbook_numbers3_test src/cookbook_numbers3_test.cpp )
	target_link_libraries( cookbook_numbers3_test PRIVATE test Boost::headers )
	add_test( NAME cookbook_numbers3_test COMMAND cookbook_numbers3_test ./cookbook_numbers3.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
	add_dependencies( ci_tests cookbook_numbers3_test )
	add_dependencies( full cookbook_numbers3_test )
endif()

add_executable( cookbook_unknown_types_and_delayed_parsing1_test src/cookbook_unknown_types_and_raw_parsing1_test.cpp )
target_link_libraries( cookbook_unknown_types_and_delayed_parsing1_test PRIVATE json_test )
add_test( NAME cookbook_unknown_types_and_delayed_parsing1_test COMMAND cookbook_unknown_types_and_delayed_parsing1_test ./cookbook_unknown_types_and_delayed_parsing1.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_unknown_types_and_delayed_parsing1_test )
add_dependencies( full cookbook_unknown_types_and_delayed_parsing1_test )

add_executable( cookbook_unknown_types_and_delayed_parsing2_test src/cookbook_unknown_types_and_raw_parsing2_test.cpp )
target_link_libraries( cookbook_unknown_types_and_delayed_parsing2_test PRIVATE json_test )
add_test( NAME cookbook_unknown_types_and_delayed_parsing2_test COMMAND cookbook_unknown_types_and_delayed_parsing2_test ./cookbook_unknown_types_and_delayed_parsing2.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_unknown_types_and_delayed_parsing2_test )
add_dependencies( full cookbook_unknown_types_and_delayed_parsing2_test )

add_executable( cookbook_unknown_types_and_delayed_parsing3_test src/cookbook_unknown_types_and_raw_parsing3_test.cpp )
target_link_libraries( cookbook_unknown_types_and_delayed_parsing3_test PRIVATE json_test )
add_test( NAME cookbook_unknown_types_and_delayed_parsing3_test COMMAND cookbook_unknown_types_and_delayed_parsing3_test )
add_dependencies( ci_tests cookbook_unknown_types_and_delayed_parsing3_test )
add_dependencies( full cookbook_unknown_types_and_delayed_parsing3_test )

add_executable( cookbook_aliases1_test src/cookbook_aliases1_test.cpp )
target_link_libraries( cookbook_aliases1_test PRIVATE json_test )
add_test( NAME cookbook_aliases1_test COMMAND cookbook_aliases1_test ./cookbook_aliases1.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_aliases1_test )
add_dependencies( full cookbook_aliases1_test )

add_executable( cookbook_class_alternate_test src/cookbook_class_alternate1_test.cpp )
target_link_libraries( cookbook_class_alternate_test PRIVATE json_test )
add_test( NAME cookbook_class_alternate_test COMMAND cookbook_class_alternate_test WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_class_alternate_test )
add_dependencies( full cookbook_class_alternate_test )

add_executable( cookbook_tuple1_test src/cookbook_tuple1_test.cpp )
target_link_libraries( cookbook_tuple1_test PRIVATE json_test )
add_test( NAME cookbook_tuple1_test COMMAND cookbook_tuple1_test ./cookbook_tuple1.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_tuple1_test )
add_dependencies( full cookbook_tuple1_test )

add_executable( cookbook_inserting_extracting_raw_json1_test src/cookbook_inserting_extracting_raw_json1_test.cpp )
target_link_libraries( cookbook_inserting_extracting_raw_json1_test PRIVATE json_test )
add_test( NAME cookbook_inserting_extracting_raw_json1_test COMMAND cookbook_inserting_extracting_raw_json1_test ./cookbook_inserting_extracting_raw_json1.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_inserting_extracting_raw_json1_test )
add_dependencies( full cookbook_inserting_extracting_raw_json1_test )

add_executable( cookbook_output_flags1_test src/cookbook_output_flags1_test.cpp )
target_link_libraries( cookbook_output_flags1_test PRIVATE json_test )
add_test( NAME cookbook_output_flags1_test COMMAND cookbook_output_flags1_test ./cookbook_output_flags1.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_output_flags1_test )
add_dependencies( full cookbook_output_flags1_test )

add_executable( gsoc_test src/gsoc_test.cpp )
target_link_libraries( gsoc_test PRIVATE json_test )
add_test( NAME gsoc_test COMMAND gsoc_test ./gsoc-2018.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests gsoc_test )
add_dependencies( full gsoc_test )

add_executable( stream_output_test src/stream_output_test.cpp )
target_link_libraries( stream_output_test PRIVATE json_test )
add_test( NAME stream_output_test COMMAND stream_output_test )
add_dependencies( ci_tests stream_output_test )
add_dependencies( full stream_output_test )

add_executable( int_sanity_test src/int_sanity_test.cpp )
target_link_libraries( int_sanity_test PRIVATE json_test )
add_test( NAME int_sanity_test COMMAND int_sanity_test )
add_dependencies( ci_tests int_sanity_test )
add_dependencies( full int_sanity_test )

if( DAW_JSON_FULL_TESTS )
	add_executable( nativejson_roundtrip src/nativejson_roundtrip.cpp )
	add_test( NAME nativejson_roundtrip COMMAND nativejson_roundtrip ./twitter.json ./citm_catalog.json ./canada.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
else()
	add_executable( nativejson_roundtrip EXCLUDE_FROM_ALL src/nativejson_roundtrip.cpp )
endif()
target_link_libraries( nativejson_roundtrip PRIVATE json_test )
add_dependencies( full nativejson_roundtrip )

add_executable( test_stateful_json_value src/test_stateful_json_value.cpp )
target_link_libraries( test_stateful_json_value PRIVATE json_test )
add_test( NAME test_stateful_json_value_test COMMAND test_stateful_json_value ./test_stateful_json_value.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests test_stateful_json_value )
add_dependencies( full test_stateful_json_value )


add_executable( test_details_parse_real src/test_details_parse_real.cpp )
target_link_libraries( test_details_parse_real PRIVATE json_test )
add_test( test_details_parse_real_test test_details_parse_real )
add_dependencies( ci_tests test_details_parse_real )
add_dependencies( full test_details_parse_real )

if( DAW_USE_EXCEPTIONS )
	add_executable( test_details_skip_string src/test_details_skip_string.cpp )
	target_link_libraries( test_details_skip_string PRIVATE json_test )
	add_test( test_details_skip_string_test test_details_skip_string )
	add_dependencies( ci_tests test_details_skip_string )
	add_dependencies( full test_details_skip_string )

	add_executable( test_details_parse_value_class src/test_details_parse_value_class.cpp )
	target_link_libraries( test_details_parse_value_class PRIVATE json_test )
	add_test( test_details_parse_value_class_test test_details_parse_value_class )
	add_dependencies( ci_tests test_details_parse_value_class )
	add_dependencies( full test_details_parse_value_class )
endif()

#DAW

set( DAW_JSON_BUILD_TEST_DET_PARSE_VAL_ARY ON )
if( ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" )
	if( CLANG_VERSION_MAJOR VERSION_LESS 9 )
		set( DAW_JSON_BUILD_TEST_DET_PARSE_VAL_ARY OFF )
	endif()
endif()

add_executable( test_details_parse_value_custom src/test_details_parse_value_custom.cpp )
target_link_libraries( test_details_parse_value_custom PRIVATE json_test )
add_test( test_details_parse_value_custom_test test_details_parse_value_custom )
add_dependencies( ci_tests test_details_parse_value_custom )
add_dependencies( full test_details_parse_value_custom )

if( DAW_USE_EXCEPTIONS )
	# Test requires exceptions
	if( DAW_JSON_BUILD_TEST_DET_PARSE_VAL_ARY )
		add_executable( test_details_parse_value_array src/test_details_parse_value_array.cpp )
		target_link_libraries( test_details_parse_value_array PRIVATE json_test )
		add_test( test_details_parse_value_array_test test_details_parse_value_array )
		add_dependencies( ci_tests test_details_parse_value_array )
		add_dependencies( full test_details_parse_value_array )
	endif()
	add_executable( test_details_skip_array src/test_details_skip_array.cpp )
	target_link_libraries( test_details_skip_array PRIVATE json_test )
	add_test( test_details_skip_array_test test_details_skip_array )
	add_dependencies( ci_tests test_details_skip_array )
	add_dependencies( full test_details_skip_array )

	add_executable( test_details_skip_class src/test_details_skip_class.cpp )
	target_link_libraries( test_details_skip_class PRIVATE json_test )
	add_test( test_details_skip_class_test test_details_skip_class )
	add_dependencies( ci_tests test_details_skip_class )
	add_dependencies( full test_details_skip_class )
endif()

add_executable( test_details_parse_value_null src/test_details_parse_value_null.cpp )
target_link_libraries( test_details_parse_value_null PRIVATE json_test )
add_test( test_details_parse_value_null_test test_details_parse_value_null )
add_dependencies( ci_tests test_details_parse_value_null )
add_dependencies( full test_details_parse_value_null )


add_executable( test_details_parse_value_iso8601 src/test_details_parse_value_iso8601.cpp )
target_link_libraries( test_details_parse_value_iso8601 PRIVATE json_test )
add_test( test_details_parse_value_iso8601_test test_details_parse_value_iso8601 )
add_dependencies( ci_tests test_details_parse_value_iso8601 )
add_dependencies( full test_details_parse_value_iso8601 )

if( DAW_USE_EXCEPTIONS )
	add_executable( test_details_parse_value_unsigned src/test_details_parse_value_unsigned.cpp )
	target_link_libraries( test_details_parse_value_unsigned PRIVATE json_test )
	add_test( test_details_parse_value_unsigned_test test_details_parse_value_unsigned )
	add_dependencies( ci_tests test_details_parse_value_unsigned )
	add_dependencies( full test_details_parse_value_unsigned )

	add_executable( test_details_parse_value_signed src/test_details_parse_value_signed.cpp )
	target_link_libraries( test_details_parse_value_signed PRIVATE json_test )
	add_test( test_details_parse_value_signed_test test_details_parse_value_signed )
	add_dependencies( ci_tests test_details_parse_value_signed )
	add_dependencies( full test_details_parse_value_signed )

	add_executable( test_details_parse_value_real src/test_details_parse_value_real.cpp )
	target_link_libraries( test_details_parse_value_real PRIVATE json_test )
	add_test( test_details_parse_value_real_test test_details_parse_value_real )
	add_dependencies( ci_tests test_details_parse_value_real )
	add_dependencies( full test_details_parse_value_real )

	add_executable( issue_370_exact_class_mapping_test src/issue_370_exact_class_mapping_test.cpp )
	target_link_libraries( issue_370_exact_class_mapping_test json_test )
	add_test( NAME issue_370_exact_class_mapping_test_test COMMAND issue_370_exact_class_mapping_test )
	add_dependencies( ci_tests issue_370_exact_class_mapping_test )
	add_dependencies( full issue_370_exact_class_mapping_test )

	add_executable( issue_389_test src/issue_389_test.cpp )
	target_link_libraries( issue_389_test PRIVATE json_test )
	add_test( NAME issue_389_test COMMAND issue_389_test ./issue_389.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
	add_dependencies( ci_tests issue_389_test )
	add_dependencies( full issue_389_test )

	add_executable( issue_398_test src/issue_398_test.cpp )
	target_link_libraries( issue_398_test PRIVATE json_test )
	add_test( NAME issue_398_test COMMAND issue_398_test )
	add_dependencies( ci_tests issue_398_test )
	add_dependencies( full issue_398_test )

	add_executable( issue_399_test src/issue_399_test.cpp )
	target_link_libraries( issue_399_test PRIVATE json_test )
	add_test( NAME issue_399_test COMMAND issue_399_test )
	add_dependencies( ci_tests issue_399_test )
	add_dependencies( full issue_399_test )

	add_executable( issue_402_test src/issue_402_test.cpp )
	target_link_libraries( issue_402_test PRIVATE json_test )
	add_test( NAME issue_402_test COMMAND issue_402_test )
	add_dependencies( ci_tests issue_402_test )
	add_dependencies( full issue_402_test )

	add_executable( issue_409_test src/issue_409_test.cpp )
	target_link_libraries( issue_409_test PRIVATE json_test )
	add_test( NAME issue_409_test COMMAND issue_409_test )
	add_dependencies( ci_tests issue_409_test )
	add_dependencies( full issue_409_test )

	add_executable( issue_413_test src/issue_413_test.cpp )
	target_link_libraries( issue_413_test PRIVATE json_test )
	add_test( NAME issue_413_test COMMAND issue_413_test )
	add_dependencies( ci_tests issue_413_test )
	add_dependencies( full issue_413_test )

endif()

add_executable( test_details_skip_number src/test_details_skip_number.cpp )
target_link_libraries( test_details_skip_number PRIVATE json_test )
add_test( test_details_skip_number_test test_details_skip_number )
add_dependencies( ci_tests test_details_skip_number )
add_dependencies( full test_details_skip_number )

add_executable( strings_test src/strings_test.cpp )
target_link_libraries( strings_test PRIVATE json_test )
add_test( NAME strings_test COMMAND strings_test ./strings.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests strings_test )
add_dependencies( full strings_test )

add_executable( strings_escaped_test src/strings_escaped_test.cpp )
target_link_libraries( strings_escaped_test PRIVATE json_test )
add_test( NAME strings_escaped_test COMMAND strings_escaped_test ./strings_escaped.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests strings_escaped_test )
add_dependencies( full strings_escaped_test )

add_executable( numbers_test src/numbers_test.cpp )
target_link_libraries( numbers_test PRIVATE json_test )
add_test( NAME numbers_test COMMAND numbers_test ./numbers.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests numbers_test )
add_dependencies( full numbers_test )

add_executable( daw_json_iostream_test src/daw_json_iostream_test.cpp )
target_link_libraries( daw_json_iostream_test PRIVATE json_test )
add_test( NAME daw_json_iostream_test COMMAND daw_json_iostream_test )
add_dependencies( ci_tests daw_json_iostream_test )
add_dependencies( full daw_json_iostream_test )

add_executable( daw_json_minify src/daw_json_minify.cpp )
target_link_libraries( daw_json_minify PRIVATE json_test )
add_dependencies( full daw_json_minify )

add_executable( daw_json_roundtrip src/daw_json_roundtrip.cpp )
target_link_libraries( daw_json_roundtrip PRIVATE json_test )
add_dependencies( ci_tests daw_json_roundtrip )
add_dependencies( full daw_json_roundtrip )

add_executable( daw_json_minify_full src/daw_json_minify_full.cpp )
target_link_libraries( daw_json_minify_full PRIVATE json_test )
add_dependencies( ci_tests daw_json_minify_full )
add_dependencies( full daw_json_minify_full )

add_executable( test_array_of_ordered src/test_array_of_ordered.cpp )
target_link_libraries( test_array_of_ordered PRIVATE json_test )
add_dependencies( ci_tests test_array_of_ordered )
add_dependencies( full test_array_of_ordered )

add_executable( test_details_parse_options src/test_details_parse_options.cpp )
target_link_libraries( test_details_parse_options PRIVATE json_test )
add_dependencies( ci_tests test_details_parse_options )
add_dependencies( full test_details_parse_options )

add_executable( test_json_checked_number src/test_json_checked_number.cpp )
target_link_libraries( test_json_checked_number PRIVATE json_test )
add_test( test_json_checked_number_test test_json_checked_number )
add_dependencies( ci_tests test_json_checked_number )
add_dependencies( full test_json_checked_number )

add_executable( test_json_date src/test_json_date.cpp )
target_link_libraries( test_json_date PRIVATE json_test )
add_test( test_json_date_test test_json_date )
add_dependencies( ci_tests test_json_date )
add_dependencies( full test_json_date )

add_executable( test_json_tuple src/test_json_tuple.cpp )
target_link_libraries( test_json_tuple PRIVATE json_test )
add_test( test_json_tuple_test test_json_tuple )
add_dependencies( ci_tests test_json_tuple )
add_dependencies( full test_json_tuple )

add_executable( test_json_array src/test_json_array.cpp )
target_link_libraries( test_json_array PRIVATE json_test )
add_test( test_json_array_test test_json_array )
add_dependencies( ci_tests test_json_array )
add_dependencies( full test_json_array )

add_executable( test_json_key_value_array src/test_json_key_value_array.cpp )
target_link_libraries( test_json_key_value_array PRIVATE json_test )
add_test( test_json_key_value_array_test test_json_key_value_array )
add_dependencies( ci_tests test_json_key_value_array )
add_dependencies( full test_json_key_value_array )

add_executable( test_json_raw src/test_json_raw.cpp )
target_link_libraries( test_json_raw PRIVATE json_test )
add_test( test_json_raw_test test_json_raw )
add_dependencies( ci_tests test_json_raw )
add_dependencies( full test_json_raw )

add_executable( test_json_iterator src/test_json_iterator.cpp )
target_link_libraries( test_json_iterator PRIVATE json_test )
add_test( test_json_iterator_test test_json_iterator )
add_dependencies( ci_tests test_json_iterator )
add_dependencies( full test_json_iterator )

add_executable( test_json_sized_array src/test_json_sized_array.cpp )
target_link_libraries( test_json_sized_array PRIVATE json_test )
add_test( test_json_sized_array_test test_json_sized_array )
add_dependencies( ci_tests test_json_sized_array )
add_dependencies( full test_json_sized_array )

add_executable( test_json_intrusive_variant src/test_json_intrusive_variant.cpp )
target_link_libraries( test_json_intrusive_variant PRIVATE json_test )
add_test( test_json_intrusive_variant_test test_json_intrusive_variant )
add_dependencies( ci_tests test_json_intrusive_variant )
add_dependencies( full test_json_intrusive_variant )

add_executable( utf16_string_test src/utf16_string_test.cpp )
target_link_libraries( utf16_string_test PRIVATE json_test )
add_test( NAME utf16_string_test COMMAND utf16_string_test ./utf16_test.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests utf16_string_test )
add_dependencies( full utf16_string_test )

add_executable( json_member_test src/json_member_test.cpp )
target_link_libraries( json_member_test PRIVATE json_test )
add_test( NAME json_member_test COMMAND json_member_test WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests json_member_test )
add_dependencies( full json_member_test )

add_executable( int_ptr_test src/int_ptr_test.cpp )
target_link_libraries( int_ptr_test PRIVATE json_test )
add_test( NAME int_ptr_test COMMAND int_ptr_test WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests int_ptr_test )
add_dependencies( full int_ptr_test )

add_executable( out_of_order_test src/out_of_order_test.cpp )
target_link_libraries( out_of_order_test PRIVATE json_test )
add_test( NAME out_of_order_test COMMAND out_of_order_test )
add_dependencies( ci_tests out_of_order_test )
add_dependencies( full out_of_order_test )

if( NOT EMSCRIPTEN AND ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" AND NOT MSVC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 13 )
	# Only clang is supported for fuzzing
	add_executable( daw_json_fuzzing EXCLUDE_FROM_ALL src/daw_json_fuzzing.cpp )
	target_link_libraries( daw_json_fuzzing PRIVATE json_test "-fsanitize=fuzzer,address,undefined" )
	target_compile_options( daw_json_fuzzing PRIVATE -fsanitize=fuzzer,address,undefined -fno-sanitize-recover=undefined -O0 -g -march=native -fsanitize-coverage=trace-cmp )

	add_executable( daw_json_fuzzing_twitter EXCLUDE_FROM_ALL src/daw_json_fuzzing_twitter.cpp )
	target_link_libraries( daw_json_fuzzing_twitter PRIVATE json_test "-fsanitize=fuzzer,address,undefined" )
	target_compile_options( daw_json_fuzzing_twitter PRIVATE -fsanitize=fuzzer,address,undefined -fno-sanitize-recover=undefined -O0 -g -march=native -fsanitize-coverage=trace-cmp )

	add_executable( daw_json_fuzzing_gsoc EXCLUDE_FROM_ALL src/daw_json_fuzzing_gsoc.cpp )
	target_link_libraries( daw_json_fuzzing_gsoc PRIVATE json_test "-fsanitize=fuzzer,address,undefined" )
	target_compile_options( daw_json_fuzzing_gsoc PRIVATE -fsanitize=fuzzer,address,undefined -fno-sanitize-recover=undefined -O0 -g -march=native -fsanitize-coverage=trace-cmp )
else()
	message( STATUS "Fuzzing support disabled for compiler: ${CMAKE_CXX_COMPILER_ID} is not supported.  Only Clang(excluding AppleClang)" )
endif()

add_executable( daw_json_fuzzing_replay EXCLUDE_FROM_ALL src/daw_json_fuzzing_replay.cpp )
target_link_libraries( daw_json_fuzzing_replay PRIVATE json_test )
if( ${CMAKE_CXX_COMPILER_ID} STREQUAL "AppleClang" )
	target_link_libraries( daw_json_fuzzing_replay PRIVATE json_test "-fsanitize=address" )
	target_compile_options( daw_json_fuzzing_replay PRIVATE -fsanitize=address -fno-sanitize-recover=undefined -g )
elseif( ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" )
	target_link_libraries( daw_json_fuzzing_replay PRIVATE json_test "-fsanitize=address" )
	target_compile_options( daw_json_fuzzing_replay PRIVATE -fsanitize=address -fno-sanitize-recover=undefined -g )
else()
	# MSVC is not supported here and Gcc(at least at v10.3.0) has issues with sanitzers and constexpr.
	# This is often char_ptr == nullptr is not a constant expression type error
	target_link_libraries( daw_json_fuzzing_replay PRIVATE json_test )
endif()

add_executable( daw_json_fuzzing_twitter_replay EXCLUDE_FROM_ALL src/daw_json_fuzzing_twitter_replay.cpp )
target_link_libraries( daw_json_fuzzing_twitter_replay PRIVATE json_test )
if( ${CMAKE_CXX_COMPILER_ID} STREQUAL "AppleClang" )
	target_link_libraries( daw_json_fuzzing_twitter_replay PRIVATE json_test "-fsanitize=address" )
	target_compile_options( daw_json_fuzzing_twitter_replay PRIVATE -fsanitize=address -fno-sanitize-recover=undefined -g )
elseif( ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" )
	target_link_libraries( daw_json_fuzzing_twitter_replay PRIVATE json_test "-fsanitize=address" )
	target_compile_options( daw_json_fuzzing_twitter_replay PRIVATE -fsanitize=address,undefined -fno-sanitize-recover=undefined -g )
else()
	# MSVC is not supported here and Gcc(at least at v10.3.0) has issues with sanitzers and constexpr.
	# This is often char_ptr == nullptr is not a constant expression type error
	target_link_libraries( daw_json_fuzzing_twitter_replay PRIVATE json_test )
endif()


set( DAW_JSON_BUILD_SCHEMA_TEST ON )
if( ${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" )
	if( CLANG_VERSION_MAJOR VERSION_LESS 10 )
		set( DAW_JSON_BUILD_SCHEMA_TEST OFF )
	endif()
endif()
if( ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" )
	if( CLANG_VERSION_MAJOR VERSION_LESS 9 )
		set( DAW_JSON_BUILD_SCHEMA_TEST OFF )
	endif()
endif()

if( DAW_JSON_BUILD_SCHEMA_TEST )
	add_executable( daw_json_schema_test src/daw_json_schema_test.cpp )
	target_link_libraries( daw_json_schema_test PRIVATE json_test )
	add_test( NAME daw_json_schema_test COMMAND daw_json_schema_test WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
	add_dependencies( ci_tests daw_json_schema_test )
	add_dependencies( full daw_json_schema_test )
endif()

add_executable( variant_on_members src/variant_on_members.cpp )
target_link_libraries( variant_on_members json_test )
add_test( NAME variant_on_members_test COMMAND variant_on_members )
add_dependencies( ci_tests variant_on_members )
add_dependencies( full variant_on_members )

add_executable( json_lines_test src/json_lines_test.cpp )
target_link_libraries( json_lines_test json_test )
add_test( NAME json_lines_test_test COMMAND json_lines_test )
add_dependencies( ci_tests json_lines_test )
add_dependencies( full json_lines_test )

add_executable( issue_334_test src/issue_334_test.cpp )
target_link_libraries( issue_334_test json_test )
add_test( NAME issue_334_test_test COMMAND issue_334_test )
add_dependencies( ci_tests issue_334_test )
add_dependencies( full issue_334_test )

add_executable( issue_336_test src/issue_336_test.cpp )
target_link_libraries( issue_336_test json_test )
add_test( NAME issue_336_test_test COMMAND issue_336_test )
add_dependencies( ci_tests issue_336_test )
add_dependencies( full issue_336_test )

add_executable( issue_357_test src/issue_357_test.cpp )
target_link_libraries( issue_357_test json_test )
add_test( NAME issue_357_test_test COMMAND issue_357_test )
add_dependencies( ci_tests issue_357_test )
add_dependencies( full issue_357_test )

add_executable( issue_359_test src/issue_359_test.cpp )
target_link_libraries( issue_359_test json_test )
add_test( NAME issue_359_test_test COMMAND issue_359_test )
add_dependencies( ci_tests issue_359_test )
add_dependencies( full issue_359_test )

add_executable( issue_361_test src/issue_361_test.cpp )
target_link_libraries( issue_361_test PRIVATE json_test )
add_test( NAME issue_361_test COMMAND issue_361_test ./issue_361.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests issue_361_test )
add_dependencies( full issue_361_test )

#add_executable( issue_373_empty_string_nullable_test src/issue_373_empty_string_nullable_test.cpp )
#target_link_libraries( issue_373_empty_string_nullable_test PRIVATE json_test )
#add_test( NAME issue_373_empty_string_nullable_test COMMAND issue_373_empty_string_nullable_test ./issue_373_empty_string_nullable.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
#add_dependencies( ci_tests issue_373_empty_string_nullable_test )
#add_dependencies( full issue_373_empty_string_nullable_test )

add_executable( issue_406_test src/issue_406_test.cpp )
target_link_libraries( issue_406_test PRIVATE json_test )
add_test( NAME issue_406_test COMMAND issue_406_test WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests issue_406_test )
add_dependencies( full issue_406_test )

add_executable( issue_418_test src/issue_418_test.cpp )
target_link_libraries( issue_418_test PRIVATE json_test )
add_test( NAME issue_418_test COMMAND issue_418_test WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests issue_418_test )
add_dependencies( full issue_418_test )

add_executable( issue_421_test EXCLUDE_FROM_ALL src/issue_421_test.cpp )
target_link_libraries( issue_421_test PRIVATE json_test )

add_executable( issue_428_test src/issue_428_test.cpp )
target_link_libraries( issue_428_test PRIVATE json_test )
add_test( NAME issue_428_test COMMAND issue_428_test WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests issue_428_test )
add_dependencies( full issue_428_test )

find_package( magic_enum CONFIG )
if( magic_enum_FOUND )
	add_executable( issue_433_test src/issue_433_test.cpp )
	target_link_libraries( issue_433_test PRIVATE json_test magic_enum::magic_enum )
	add_test( NAME issue_433_test COMMAND issue_433_test WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
	add_dependencies( ci_tests issue_433_test )
	add_dependencies( full issue_433_test )
endif()

add_executable( issue_439_test src/issue_439_test.cpp )
target_link_libraries( issue_439_test PRIVATE json_test )
add_test( NAME issue_439_test COMMAND issue_439_test WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests issue_439_test )
add_dependencies( full issue_439_test )

add_executable( multi_tu_test src/multi_tu_p0_test.cpp src/multi_tu_p1_test.cpp )
target_link_libraries( multi_tu_test json_test )
add_test( NAME multi_tu_test_test COMMAND multi_tu_test )
add_dependencies( ci_tests multi_tu_test )
add_dependencies( full multi_tu_test )

add_executable( carray_test src/carray_test.cpp )
target_link_libraries( carray_test json_test )
add_test( NAME carray_test_test COMMAND carray_test )
add_dependencies( ci_tests carray_test )
add_dependencies( full carray_test )

add_executable( base_child_class_test src/base_child_class_test.cpp )
target_link_libraries( base_child_class_test json_test )
add_test( NAME base_child_class_test_test COMMAND base_child_class_test )
add_dependencies( ci_tests base_child_class_test )
add_dependencies( full base_child_class_test )

add_executable( error_handling_bench_test EXCLUDE_FROM_ALL src/error_handling_bench_test.cpp )
target_link_libraries( error_handling_bench_test json_test )
if( DEFINED MSVC AND NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" )
	target_compile_options( error_handling_bench_test PRIVATE /wd4324 /wd4611 )
endif()

add_executable( json_bench_viewer EXCLUDE_FROM_ALL src/json_bench_viewer.cpp )
target_link_libraries( json_bench_viewer json_test )

if( Threads_FOUND )
	add_executable( json_lines_bench_test EXCLUDE_FROM_ALL src/json_lines_bench_test.cpp )
	target_link_libraries( json_lines_bench_test json_test ${CMAKE_THREAD_LIBS_INIT} )
endif()

if( DAW_JSON_USE_REFLECTION )
	add_executable( daw_json_link_reflection_test src/daw_json_link_reflection_test.cpp )
	target_link_libraries( daw_json_link_reflection_test json_test )
	add_test( NAME daw_json_link_reflection_test_test COMMAND daw_json_link_reflection_test )
	add_dependencies( ci_tests daw_json_link_reflection_test )
	add_dependencies( full daw_json_link_reflection_test )
endif()

# **************************************************
# JSON Benchmark
# **************************************************

include( ./cmake/git_properties.cmake )
if( GIT_FOUND )
	message( STATUS "Git revision: ${SOURCE_CONTROL_REVISION}" )
	add_executable( json_benchmark EXCLUDE_FROM_ALL src/json_benchmark.cpp )
	target_compile_definitions( json_benchmark PRIVATE -DSOURCE_CONTROL_REVISION="${BUILD_VERSION}" )
	target_link_libraries( json_benchmark PRIVATE json_test )
	if( DEFINED MSVC AND NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" )
		add_compile_options( "/bigobj" )
	endif()

	cmake_host_system_information( RESULT _proc_desc QUERY PROCESSOR_DESCRIPTION )
	string( REPLACE "#" "" _proc_desc ${_proc_desc} )
	cmake_host_system_information( RESULT _os_name QUERY OS_NAME )
	string( REPLACE "#" "" _os_name ${_os_name} )
	cmake_host_system_information( RESULT _os_rel QUERY OS_RELEASE )
	string( REPLACE "#" "" _os_rel ${_os_rel} )
	cmake_host_system_information( RESULT _os_ver QUERY OS_VERSION )
	string( REPLACE "#" "" _os_ver ${_os_ver} )
	cmake_host_system_information( RESULT _os_plat QUERY OS_PLATFORM )
	string( REPLACE "#" "" _os_plat ${_os_plat} )
	target_compile_definitions( json_benchmark PRIVATE -DPROCESSOR_DESCRIPTION="${_proc_desc}" )
	target_compile_definitions( json_benchmark PRIVATE -DOS_NAME="${_os_name}" )
	target_compile_definitions( json_benchmark PRIVATE -DOS_RELEASE="${_os_rel}" )
	target_compile_definitions( json_benchmark PRIVATE -DOS_VERSION="${_os_ver}" )
	target_compile_definitions( json_benchmark PRIVATE -DOS_PLATFORM="${_os_plat}" )
	target_compile_definitions( json_benchmark PRIVATE -DBUILD_TYPE="${CMAKE_BUILD_TYPE}" )
endif()
# **************************************************
 
