From 800c141a879f8faa34b891e2897fc421c60a0119 Mon Sep 17 00:00:00 2001 From: Andreas Tsouchlos Date: Mon, 22 Nov 2021 10:53:55 +0100 Subject: [PATCH] Added more tests; is_digit(s, i) -> is_digit(i); Minor other stuff --- inc/ConstString.h | 3 ++ inc/format.h | 12 ++++++-- inc/parse.h | 16 +++++++---- test/CMakeLists.txt | 1 + test/src/format.cpp | 48 ++++++++++++++++++++++++++++++- test/src/parse.cpp | 69 +++++++++++++++++++++++++++++++++++++++------ 6 files changed, 130 insertions(+), 19 deletions(-) diff --git a/inc/ConstString.h b/inc/ConstString.h index 31f6a68..c531dcd 100644 --- a/inc/ConstString.h +++ b/inc/ConstString.h @@ -2,6 +2,9 @@ #define LOGGER_CONSTSTRING_H +#include + + namespace detail { diff --git a/inc/format.h b/inc/format.h index 74fb01f..839e3a4 100644 --- a/inc/format.h +++ b/inc/format.h @@ -35,11 +35,17 @@ constexpr int get_output_len() { template constexpr std::array get_init_array() { + std::array result; + if constexpr (zeroed) { - return {'0'}; + for (auto& c : result) + c = '0'; } else { - return {' '}; + for (auto& c : result) + c = ' '; } + + return result; } @@ -148,7 +154,7 @@ constexpr std::array()> format(args_t... args) { constexpr auto parse_result = detail::parse_string(); static_assert(parse_result.is_valid, "Syntax error in format string"); - std::array()> result; + std::array()> result = {}; return detail::format_args(result, args...); } diff --git a/inc/parse.h b/inc/parse.h index 3d9c93e..8107a28 100644 --- a/inc/parse.h +++ b/inc/parse.h @@ -95,17 +95,21 @@ constexpr int get_ast_len() { */ -template -constexpr bool is_digit(ConstString s, unsigned i) { +template +constexpr bool is_digit(unsigned i) { return (s[i] > 47) && (s[i] < 58); } template -constexpr parse_result_t parse_number(unsigned i) { - int number = 0; +constexpr parse_result_t parse_number(unsigned i) { + unsigned number = 0; - while ((i < s.size()) && is_digit(s, i)) { + if (!is_digit(i)) { + return {false, i, number}; + } + + while ((i < s.size()) && is_digit(i)) { number = number * 10; number += (s[i] - 48); ++i; @@ -184,7 +188,7 @@ constexpr parse_result_t parse_fmt_string(unsigned i) { result.has_zero_padding = true; } - if (is_digit(s, i)) { + if (is_digit(i)) { auto [is_valid, new_i, number] = parse_number(i); if (!is_valid) return {false, i, result}; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 892a542..087a232 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -18,4 +18,5 @@ endmacro() package_add_test(utility_test src/utility.cpp) package_add_test(parse_test src/parse.cpp) +package_add_test(format_test src/format.cpp) diff --git a/test/src/format.cpp b/test/src/format.cpp index edae684..882b48f 100644 --- a/test/src/format.cpp +++ b/test/src/format.cpp @@ -1,2 +1,48 @@ #include -#include \ No newline at end of file +#include + + +using namespace detail; + + +TEST(Format, positive_int) { + constexpr std::array control1 = {'0', '0', '0', '2', + '2', '2', '2', '2'}; + constexpr std::array formatted1 = format<"{:08}">(22222); + + constexpr std::array control2 = {' ', ' ', ' ', '2', + '2', '2', '2', '2'}; + constexpr std::array formatted2 = format<"{:8}">(22222); + + constexpr std::array control3 = {'0', '0', '0', '1', + '2', '3', '4', '5'}; + constexpr std::array formatted3 = format<"{:08.4}">(12345); + + constexpr std::array control4 = {'6', '7', '8', '9'}; + constexpr std::array formatted4 = format<"{:4}">(6789); + + EXPECT_EQ(control1, formatted1); + EXPECT_EQ(control2, formatted2); + EXPECT_EQ(control3, formatted3); + EXPECT_EQ(control4, formatted4); +} + +//TEST(Format, negative_int) { +// // TODO +// EXPECT_EQ(true, false); +//} +// +//TEST(Format, positive_float) { +// // TODO +// EXPECT_EQ(true, false); +//} +// +//TEST(Format, negative_float) { +// // TODO +// EXPECT_EQ(true, false); +//} +// +//TEST(Format, string) { +// // TODO +// EXPECT_EQ(true, false); +//} \ No newline at end of file diff --git a/test/src/parse.cpp b/test/src/parse.cpp index d13df82..7c61055 100644 --- a/test/src/parse.cpp +++ b/test/src/parse.cpp @@ -5,10 +5,26 @@ using namespace detail; +TEST(Parse, parse_number) { + constexpr auto pr1 = parse_number<"0">(0); + constexpr auto pr2 = parse_number<"9">(0); + constexpr auto pr3 = parse_number<"abcd16777216">(4); + constexpr auto pr4 = parse_number<"009">(0); + constexpr auto pr5 = parse_number<"10101010109">(6); + constexpr auto pr6 = parse_number<"">(0); + + EXPECT_EQ(pr1.value, 0); + EXPECT_EQ(pr2.value, 9); + EXPECT_EQ(pr3.value, 16777216); + EXPECT_EQ(pr4.value, 9); + EXPECT_EQ(pr5.value, 10109); + EXPECT_EQ(pr6.is_valid, false); +} + TEST(Parse, ast_node) { - ast_node_t ast_node1{'a'}; - ast_node_t ast_node2{'a'}; - ast_node_t ast_node3{'b'}; + constexpr ast_node_t ast_node1{'a'}; + constexpr ast_node_t ast_node2{'a'}; + constexpr ast_node_t ast_node3{'b'}; EXPECT_EQ(ast_node1 == ast_node2, true); EXPECT_EQ(ast_node1 == ast_node3, false); @@ -21,25 +37,60 @@ TEST(Parse, ast_chars_only) { EXPECT_EQ(parse_string<"abcdefgh">().value, control); } +TEST(Parse, syntax) { + constexpr auto pr1 = parse_string<"af {:012.4f}">(); + constexpr auto pr2 = parse_string<"af {:.4f}">(); + constexpr auto pr3 = parse_string<"asdf}{">(); + constexpr auto pr4 = parse_string<"{:.}">(); + constexpr auto pr5 = parse_string<"asdf{">(); + constexpr auto pr6 = parse_string<"asd{d}:.8">(); + + EXPECT_EQ(pr1.is_valid, true); + EXPECT_EQ(pr2.is_valid, true); + EXPECT_EQ(pr3.is_valid, false); + EXPECT_EQ(pr4.is_valid, false); + EXPECT_EQ(pr5.is_valid, false); + EXPECT_EQ(pr6.is_valid, false); +} + TEST(Parse, ast_nodes_only) { fmt_node_t fmt_node0 = {true, 6, 3, FormatType::s}; fmt_node_t fmt_node1; fmt_node1.length = 8; - fmt_node1.type = FormatType::s; + fmt_node1.type = FormatType::s; fmt_node_t fmt_node2; fmt_node2.precision = 4; - fmt_node_t fmt_node3 = {}; + fmt_node_t fmt_node3 = {true, 456765, 1234, FormatType::f}; fmt_node_t fmt_node4 = {}; fmt_node_t fmt_node5 = {}; fmt_node_t fmt_node6 = {}; fmt_node_t fmt_node7 = {}; - std::array control = { - fmt_node0, fmt_node1, fmt_node2, fmt_node3, - fmt_node4, fmt_node5, fmt_node6, fmt_node7}; + std::array control = {fmt_node0, fmt_node1, fmt_node2, + fmt_node3, fmt_node4, fmt_node5, + fmt_node6, fmt_node7}; - EXPECT_EQ(parse_string<"{:06.3}{:8s}{:.4}{}{}{}{}{}">().value, control); + EXPECT_EQ(parse_string<"{:06.3}{:8s}{:.4}{:0456765.1234f}{}{}{}{}">().value, + control); } + +TEST(Parse, ast_chars_and_nodes) { + fmt_node_t fmt_node0 = {true, 6, 3, FormatType::s}; + + fmt_node_t fmt_node1; + fmt_node1.length = 8; + fmt_node1.type = FormatType::s; + + fmt_node_t fmt_node2; + fmt_node2.precision = 4; + + + std::array control = {fmt_node0, 'a', 'b', ' ', + ' ', 'd', fmt_node1, fmt_node2, + ' ', ' ', '-'}; + + EXPECT_EQ(parse_string<"{:06.3}ab d{:8s}{:.4} -">().value, control); +} \ No newline at end of file