summaryrefslogtreecommitdiff
path: root/tomlplusplus/tests/formatters.cpp
diff options
context:
space:
mode:
authorMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-02 18:44:05 +0300
committerMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-02 18:44:05 +0300
commit0b24459ac12b6cf9fd5a401d647796ca254a8fa8 (patch)
treef2fd66e2476976a51e2a51330fd95dc6e87b24c1 /tomlplusplus/tests/formatters.cpp
parentb85e90fc3480da0e6a48da73201a0b22488cc650 (diff)
parent1c8b7466e4946fcc3bf20484c0e1d001202cca5a (diff)
downloadProject-Tick-0b24459ac12b6cf9fd5a401d647796ca254a8fa8.tar.gz
Project-Tick-0b24459ac12b6cf9fd5a401d647796ca254a8fa8.zip
Add 'tomlplusplus/' from commit '1c8b7466e4946fcc3bf20484c0e1d001202cca5a'
git-subtree-dir: tomlplusplus git-subtree-mainline: b85e90fc3480da0e6a48da73201a0b22488cc650 git-subtree-split: 1c8b7466e4946fcc3bf20484c0e1d001202cca5a
Diffstat (limited to 'tomlplusplus/tests/formatters.cpp')
-rw-r--r--tomlplusplus/tests/formatters.cpp332
1 files changed, 332 insertions, 0 deletions
diff --git a/tomlplusplus/tests/formatters.cpp b/tomlplusplus/tests/formatters.cpp
new file mode 100644
index 0000000000..a0cd35f914
--- /dev/null
+++ b/tomlplusplus/tests/formatters.cpp
@@ -0,0 +1,332 @@
+// This file is a part of toml++ and is subject to the the terms of the MIT license.
+// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
+
+#include "tests.hpp"
+
+namespace
+{
+ template <typename Formatter, typename T>
+ static auto format_to_string(const T& obj,
+ format_flags flags = Formatter::default_flags,
+ format_flags exclude_flags = format_flags::none)
+ {
+ std::stringstream ss;
+ ss << "*****\n" << Formatter{ obj, flags & ~(exclude_flags) } << "\n*****";
+ return ss.str();
+ }
+
+ struct char32_printer
+ {
+ char32_t value;
+
+ friend std::ostream& operator<<(std::ostream& os, const char32_printer& p)
+ {
+ if (p.value <= U'\x1F')
+ return os << '\'' << impl::control_char_escapes[static_cast<size_t>(p.value)] << '\'';
+ else if (p.value == U'\x7F')
+ return os << "'\\u007F'"sv;
+ else if (p.value < 127u)
+ return os << '\'' << static_cast<char>(static_cast<uint8_t>(p.value)) << '\'';
+ else
+ return os << static_cast<uint_least32_t>(p.value);
+ }
+ };
+
+ struct string_difference
+ {
+ source_position position;
+ size_t index;
+ char32_t a, b;
+
+ friend std::ostream& operator<<(std::ostream& os, const string_difference& diff)
+ {
+ if (diff.a && diff.b && diff.a != diff.b)
+ os << char32_printer{ diff.a } << " vs "sv << char32_printer{ diff.b } << " at "sv;
+ return os << diff.position << ", index "sv << diff.index;
+ }
+ };
+
+ static optional<string_difference> find_first_difference(std::string_view str_a, std::string_view str_b) noexcept
+ {
+ string_difference diff{ { 1u, 1u } };
+ impl::utf8_decoder a, b;
+
+ for (size_t i = 0, e = std::min(str_a.length(), str_b.length()); i < e; i++, diff.index++)
+ {
+ a(static_cast<uint8_t>(str_a[i]));
+ b(static_cast<uint8_t>(str_b[i]));
+ if (a.has_code_point() != b.has_code_point() || a.error() != b.error())
+ return diff;
+
+ if (a.error())
+ {
+ a.reset();
+ b.reset();
+ continue;
+ }
+
+ if (!a.has_code_point())
+ continue;
+
+ if (a.codepoint != b.codepoint)
+ {
+ diff.a = a.codepoint;
+ diff.b = b.codepoint;
+ return diff;
+ }
+
+ if (a.codepoint == U'\n')
+ {
+ diff.position.line++;
+ diff.position.column = 1u;
+ }
+ else
+ diff.position.column++;
+ }
+ if (str_a.length() != str_b.length())
+ return diff;
+ return {};
+ }
+}
+
+#define CHECK_FORMATTER(formatter, data, expected) \
+ do \
+ { \
+ const auto str = format_to_string<formatter>(data); \
+ const auto diff = find_first_difference(str, expected); \
+ if (diff) \
+ FORCE_FAIL("string mismatch: "sv << *diff); \
+ } \
+ while (false)
+
+TEST_CASE("formatters")
+{
+ const auto data_date = toml::date{ 2021, 11, 2 };
+ const auto data_time = toml::time{ 20, 33, 0 };
+ const auto data = toml::table{
+ { "integers"sv,
+ toml::table{ { "zero"sv, 0 },
+ { "one"sv, 1 },
+ { "dec"sv, 10 },
+ { "bin"sv, 10, toml::value_flags::format_as_binary },
+ { "oct"sv, 10, toml::value_flags::format_as_octal },
+ { "hex"sv, 10, toml::value_flags::format_as_hexadecimal } } },
+ { "floats"sv,
+ toml::table{ { "pos_zero"sv, +0.0 },
+ { "neg_zero"sv, -0.0 },
+ { "one"sv, 1.0 },
+ { "pos_inf"sv, +std::numeric_limits<double>::infinity() },
+ { "neg_inf"sv, -std::numeric_limits<double>::infinity() },
+ { "pos_nan"sv, +std::numeric_limits<double>::quiet_NaN() },
+ { "neg_nan"sv, -std::numeric_limits<double>::quiet_NaN() }
+
+ } },
+
+ { "dates and times"sv,
+ toml::table{
+
+ { "dates"sv, toml::table{ { "val"sv, data_date } } },
+
+ { "times"sv, toml::table{ { "val"sv, data_time } } },
+
+ { "date-times"sv,
+ toml::table{
+
+ { "local"sv, toml::table{ { "val"sv, toml::date_time{ data_date, data_time } } } },
+ { "offset"sv,
+ toml::table{
+ { "val"sv, toml::date_time{ data_date, data_time, toml::time_offset{} } } } } } } } },
+
+ { "bools"sv,
+ toml::table{ { "true"sv, true }, //
+ { "false"sv, false } } },
+
+ {
+ "strings"sv,
+ toml::array{ R"()"sv,
+ R"(string)"sv,
+ R"(string with a single quote in it: ')"sv,
+ R"(string with a double quote in it: ")"sv,
+ "string with a tab: \t"sv,
+ R"(a long string to force the array over multiple lines)"sv },
+ },
+
+ { "a"sv,
+ toml::table{ { "val", true },
+ { "b"sv, toml::table{ { "val", true }, { "c"sv, toml::table{ { "val", true } } } } } } }
+
+ };
+
+ SECTION("toml_formatter")
+ {
+ static constexpr auto expected = R"(*****
+strings = [
+ '',
+ 'string',
+ "string with a single quote in it: '",
+ 'string with a double quote in it: "',
+ 'string with a tab: ',
+ 'a long string to force the array over multiple lines'
+]
+
+[a]
+val = true
+
+ [a.b]
+ val = true
+
+ [a.b.c]
+ val = true
+
+[bools]
+false = false
+true = true
+
+['dates and times'.date-times.local]
+val = 2021-11-02T20:33:00
+
+['dates and times'.date-times.offset]
+val = 2021-11-02T20:33:00Z
+
+['dates and times'.dates]
+val = 2021-11-02
+
+['dates and times'.times]
+val = 20:33:00
+
+[floats]
+neg_inf = -inf
+neg_nan = nan
+neg_zero = -0.0
+one = 1.0
+pos_inf = inf
+pos_nan = nan
+pos_zero = 0.0
+
+[integers]
+bin = 0b1010
+dec = 10
+hex = 0xA
+oct = 0o12
+one = 1
+zero = 0
+*****)"sv;
+
+ CHECK_FORMATTER(toml_formatter, data, expected);
+ }
+
+ SECTION("json_formatter")
+ {
+ static constexpr auto expected = R"(*****
+{
+ "a" : {
+ "b" : {
+ "c" : {
+ "val" : true
+ },
+ "val" : true
+ },
+ "val" : true
+ },
+ "bools" : {
+ "false" : false,
+ "true" : true
+ },
+ "dates and times" : {
+ "date-times" : {
+ "local" : {
+ "val" : "2021-11-02T20:33:00"
+ },
+ "offset" : {
+ "val" : "2021-11-02T20:33:00Z"
+ }
+ },
+ "dates" : {
+ "val" : "2021-11-02"
+ },
+ "times" : {
+ "val" : "20:33:00"
+ }
+ },
+ "floats" : {
+ "neg_inf" : "-Infinity",
+ "neg_nan" : "NaN",
+ "neg_zero" : -0.0,
+ "one" : 1.0,
+ "pos_inf" : "Infinity",
+ "pos_nan" : "NaN",
+ "pos_zero" : 0.0
+ },
+ "integers" : {
+ "bin" : 10,
+ "dec" : 10,
+ "hex" : 10,
+ "oct" : 10,
+ "one" : 1,
+ "zero" : 0
+ },
+ "strings" : [
+ "",
+ "string",
+ "string with a single quote in it: '",
+ "string with a double quote in it: \"",
+ "string with a tab: \t",
+ "a long string to force the array over multiple lines"
+ ]
+}
+*****)"sv;
+
+ CHECK_FORMATTER(json_formatter, data, expected);
+ }
+
+ SECTION("yaml_formatter")
+ {
+ static constexpr auto expected = R"(*****
+a:
+ b:
+ c:
+ val: true
+ val: true
+ val: true
+bools:
+ false: false
+ true: true
+'dates and times':
+ date-times:
+ local:
+ val: '2021-11-02T20:33:00'
+ offset:
+ val: '2021-11-02T20:33:00Z'
+ dates:
+ val: '2021-11-02'
+ times:
+ val: '20:33:00'
+floats:
+ neg_inf: -.inf
+ neg_nan: .NAN
+ neg_zero: -0.0
+ one: 1.0
+ pos_inf: .inf
+ pos_nan: .NAN
+ pos_zero: 0.0
+integers:
+ bin: 10
+ dec: 10
+ hex: 0xA
+ oct: 0o12
+ one: 1
+ zero: 0
+strings:
+ - ''
+ - string
+ - "string with a single quote in it: '"
+ - 'string with a double quote in it: "'
+ - "string with a tab: \t"
+ - 'a long string to force the array over multiple lines'
+*****)"sv;
+
+ CHECK_FORMATTER(yaml_formatter, data, expected);
+ }
+}