// This file is a part of toml++ and is subject to the the terms of the MIT license. // Copyright (c) 2019-2020 Mark Gillard // See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. // SPDX-License-Identifier: MIT #include "tests.h" bool parsing_should_succeed( std::string_view test_file, uint32_t test_line, std::string_view toml_str, pss_func&& func, std::string_view source_path) { INFO("["sv << test_file << ", line "sv << test_line << "] "sv << "parsing_should_succeed(\""sv << toml_str << "\")"sv) constexpr auto validate_table = [](table&& tabl, std::string_view path) -> table&& { INFO("Validating table source information"sv) CHECK(tabl.source().begin != source_position{}); CHECK(tabl.source().end != source_position{}); if (path.empty()) CHECK(tabl.source().path == nullptr); else { REQUIRE(tabl.source().path != nullptr); CHECK(*tabl.source().path == path); } return std::move(tabl); }; #if TOML_EXCEPTIONS try { { INFO("Parsing string directly"sv) if (func) func(validate_table(toml::parse(toml_str, source_path), source_path)); else validate_table(toml::parse(toml_str, source_path), source_path); } { INFO("Parsing from a string stream"sv) std::stringstream ss; ss.write(toml_str.data(), static_cast(toml_str.length())); if (func) func(validate_table(toml::parse(ss, source_path), source_path)); else validate_table(toml::parse(ss, source_path), source_path); } } catch (const parse_error& err) { FORCE_FAIL( "Parse error on line "sv << err.source().begin.line << ", column "sv << err.source().begin.column << ":\n"sv << err.description() ); return false; } #else { INFO("Parsing string directly"sv) parse_result result = toml::parse(toml_str, source_path); if (result) { if (func) func(validate_table(std::move(result), source_path)); else validate_table(std::move(result), source_path); } else { FORCE_FAIL( "Parse error on line "sv << result.error().source().begin.line << ", column "sv << result.error().source().begin.column << ":\n"sv << result.error().description() ); } } { INFO("Parsing from a string stream"sv) std::stringstream ss; ss.write(toml_str.data(), static_cast(toml_str.length())); parse_result result = toml::parse(ss, source_path); if (result) { if (func) func(validate_table(std::move(result), source_path)); else validate_table(std::move(result), source_path); } else { FORCE_FAIL( "Parse error on line "sv << result.error().source().begin.line << ", column "sv << result.error().source().begin.column << ":\n"sv << result.error().description() ); } } #endif return true; } bool parsing_should_fail( std::string_view test_file, uint32_t test_line, std::string_view toml_str) { INFO("["sv << test_file << ", line "sv << test_line << "] "sv << "parsing_should_fail(\""sv << toml_str << "\")"sv) #if TOML_EXCEPTIONS static constexpr auto run_tests = [](auto&& fn) { try { fn(); } catch (const parse_error&) { SUCCEED("parse_error thrown OK"sv); return true; } catch (const std::exception& exc) { FORCE_FAIL("Expected parsing failure, saw exception: "sv << exc.what()); return false; } catch (...) { FORCE_FAIL("Expected parsing failure, saw unspecified exception"sv); return false; } FORCE_FAIL("Expected parsing failure"sv); return false; }; auto result = run_tests([=]() { [[maybe_unused]] auto res = toml::parse(toml_str); }); result = result && run_tests([=]() { std::stringstream ss; ss.write(toml_str.data(), static_cast(toml_str.length())); [[maybe_unused]] auto res = toml::parse(ss); }); return result; #else static constexpr auto run_tests = [](auto&& fn) { if (parse_result result = fn(); !result) { SUCCEED("parse_error generated OK"sv); return true; } FORCE_FAIL("Expected parsing failure"sv); }; return run_tests([=]() { return toml::parse(toml_str); }) && run_tests([=]() { std::stringstream ss; ss.write(toml_str.data(), static_cast(toml_str.length())); return toml::parse(ss); }); #endif } template bool parse_expected_value(std::string_view, uint32_t, std::string_view, const int&); template bool parse_expected_value(std::string_view, uint32_t, std::string_view, const unsigned int&); template bool parse_expected_value(std::string_view, uint32_t, std::string_view, const bool&); template bool parse_expected_value(std::string_view, uint32_t, std::string_view, const float&); template bool parse_expected_value(std::string_view, uint32_t, std::string_view, const double&); template bool parse_expected_value(std::string_view, uint32_t, std::string_view, const toml::string_view&); namespace std { template class unique_ptr; } namespace Catch { template struct StringMaker>; template struct StringMaker>; template ReusableStringStream& ReusableStringStream::operator << (toml::node_view const&); template ReusableStringStream& ReusableStringStream::operator << (toml::node_view const&); namespace Detail { template std::string stringify(const node_view&); template std::string stringify(const node_view&); } }