#include "tap.hpp" #include "string.hpp" #include "types.hpp" #include "iterator.hpp" #include /////////////////////////////////////////////////////////////////////////////// void test_position (cruft::TAP::logger &tap) { char const *string = "a\nb\nc\n"; struct { int offset; int line; int column; } TESTS[] = { { 0, 0, 0 }, { 1, 1, -1 }, { 2, 1, 0 }, { 3, 2, -1 }, { 4, 2, 0 }, { 5, 3, -1 }, }; for (auto const &t: TESTS) { auto const pos = cruft::character_position ({string, strlen(string) }, string + t.offset); tap.expect ( pos.line == t.line && pos.column == t.column, "character_position %!:%!", t.line, t.column ); } } /////////////////////////////////////////////////////////////////////////////// void test_tokeniser (cruft::TAP::logger &tap) { // the string_literal prefix is required to (easily) construct a string // with an internal null character. using namespace std::literals::string_literals; const std::string csv = "\0,a,123,,this is a test,"s; // expected test data must be a std::string so we can check embedded // nulls (which are ambiguous when using a cstr). struct foo { const std::string value; const char *message; } TESTS[] = { { "\0"s, "null" }, { "a", "single letter" }, { "123", "three digits" }, { "", "empty string" }, { "this is a test", "string with spaces" }, { "", "trailing empty" } }; cruft::view src { csv.c_str (), csv.size () }; for (auto [tok, expected]: cruft::zip (cruft::tokeniser (src, ','), TESTS)) { tap.expect (equal (tok, expected.value), "%s", expected.message); } } /////////////////////////////////////////////////////////////////////////////// int main (int, char**) { cruft::TAP::logger tap; test_tokeniser (tap); test_position (tap); return tap.status (); }