File: tests.cpp

package info (click to toggle)
tomlplusplus 3.3.0%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 3,184 kB
  • sloc: cpp: 35,145; ansic: 2,220; python: 983; makefile: 25; sh: 17
file content (230 lines) | stat: -rw-r--r-- 6,997 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
// 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.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<std::streamsize>(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<std::streamsize>(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,
						 source_index expected_failure_line,
						 source_index expected_failure_column)
{
	INFO("["sv << test_file << ", line "sv << test_line << "] "sv
			   << "parsing_should_fail(\""sv << toml_str << "\")"sv)

#if TOML_EXCEPTIONS

	static constexpr auto run_tests = [](source_index ex_line, source_index ex_col, auto&& fn)
	{
		try
		{
			fn();
		}
		catch (const parse_error& err)
		{
			if (ex_line != static_cast<source_index>(-1) && err.source().begin.line != ex_line)
			{
				FORCE_FAIL("Expected parse_error at line "sv << ex_line << ", actually occured at line "sv
															 << err.source().begin.line);
				return false;
			}

			if (ex_col != static_cast<source_index>(-1) && err.source().begin.column != ex_col)
			{
				FORCE_FAIL("Expected parse_error at column "sv << ex_col << ", actually occured at column "sv
															   << err.source().begin.column);
				return false;
			}

			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(expected_failure_line,
							expected_failure_column,
							[=]() { [[maybe_unused]] auto res = toml::parse(toml_str); });
	result		= result
		  && run_tests(expected_failure_line,
					   expected_failure_column,
					   [=]()
					   {
						   std::stringstream ss;
						   ss.write(toml_str.data(), static_cast<std::streamsize>(toml_str.length()));
						   [[maybe_unused]] auto res = toml::parse(ss);
					   });
	return result;

#else

	static constexpr auto run_tests = [](source_index ex_line, source_index ex_col, auto&& fn)
	{
		if (parse_result result = fn(); !result)
		{
			if (ex_line != static_cast<source_index>(-1) && result.error().source().begin.line != ex_line)
			{
				FORCE_FAIL("Expected parse_error at line "sv << ex_line << ", actually occured at line "sv
															 << result.error().source().begin.line);
			}

			if (ex_col != static_cast<source_index>(-1) && result.error().source().begin.column != ex_col)
			{
				FORCE_FAIL("Expected parse_error at column "sv << ex_col << ", actually occured at column "sv
															   << result.error().source().begin.column);
			}

			SUCCEED("parse_error generated OK"sv);
			return true;
		}

		FORCE_FAIL("Expected parsing failure"sv);
	};

	return run_tests(expected_failure_line, expected_failure_column, [=]() { return toml::parse(toml_str); })
		&& run_tests(expected_failure_line,
					 expected_failure_column,
					 [=]()
					 {
						 std::stringstream ss;
						 ss.write(toml_str.data(), static_cast<std::streamsize>(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 std::string_view&);

namespace std
{
	template class unique_ptr<const Catch::IExceptionTranslator>;
}
namespace Catch
{
	template struct StringMaker<node_view<node>>;
	template struct StringMaker<node_view<const node>>;
	template ReusableStringStream& ReusableStringStream::operator<<(node_view<node> const&);
	template ReusableStringStream& ReusableStringStream::operator<<(node_view<const node> const&);
	namespace Detail
	{
		template std::string stringify(const node_view<node>&);
		template std::string stringify(const node_view<const node>&);
	}
}