diff --git a/README.md b/README.md index aa17e97..d07def1 100644 --- a/README.md +++ b/README.md @@ -195,10 +195,15 @@ int main(void) int main(void) { fort::Table table; - table << fort::header - << "N" << "Planet" << "Speed, km/s" << "Temperature, K" << fort::endr; + table << fort::header; + /* Fill each cell with operator[] */ + table [0][0] = "N"; + table [0][1] = "Planet"; + table [0][2] = "Speed, km/s"; + table [0][3] = "Temperature, K"; + table << fort::endr; - /* Fill with << operator */ + /* Fill with iostream operator<< */ table << 1 << "Mercury" << 47.362 << 340 << fort::endr; /* Fill row explicitly with strings */ diff --git a/example/main.cpp b/example/main.cpp index 73cafe6..4b626a8 100644 --- a/example/main.cpp +++ b/example/main.cpp @@ -37,10 +37,16 @@ void different_cell_options_example(void) void fill_table_with_data_example(void) { fort::Table table; - table << fort::header - << "N" << "Planet" << "Speed, km/s" << "Temperature, K" << fort::endr; + table << fort::header; + /* Fill each cell with operator[] */ + table [0][0] = "N"; + table [0][1] = "Planet"; + table [0][2] = "Speed, km/s"; + table [0][3] = "Temperature, K"; + table << fort::endr; - /* Fill with iostream << operator */ + + /* Fill with iostream operator<< */ table << 1 << "Mercury" << 47.362 << 340 << fort::endr; /* Fill row explicitly with strings */ diff --git a/lib/fort.hpp b/lib/fort.hpp index 993b100..a4f2898 100644 --- a/lib/fort.hpp +++ b/lib/fort.hpp @@ -155,7 +155,7 @@ public: Table &operator<<(const T &arg) { stream << arg; - if (stream.tellp()) { + if (stream.tellp() >= 0) { ft_nwrite(table, 1, stream.str().c_str()); stream.str(std::string()); } @@ -504,6 +504,53 @@ public: private: ft_table_t *table; std::stringstream stream; + +public: + + /* Iterators */ + /* todo: implement chains like table[0][0] = table [0][1] = "somethings" */ + + class table_cell_iterator + { + public: + table_cell_iterator(std::size_t row_idx, std::size_t coll_idx,Table &table) + :row_idx_(row_idx), coll_idx_(coll_idx), table_(table) {} + + table_cell_iterator& operator=(const char *str) + { + ft_set_cur_cell(table_.table, row_idx_, coll_idx_); + table_.write(str); + return *this; + } + + private: + std::size_t row_idx_; + std::size_t coll_idx_; + Table &table_; + }; + + class table_row_iterator + { + public: + table_row_iterator(std::size_t row_idx, Table &table) + :row_idx_(row_idx), table_(table) {} + + struct table_cell_iterator + operator[](std::size_t coll_idx) + { + return table_cell_iterator(row_idx_, coll_idx, table_); + } + + private: + std::size_t row_idx_; + Table &table_; + }; + + struct table_row_iterator + operator[](std::size_t row_idx) + { + return table_row_iterator(row_idx, *this); + } }; diff --git a/tests/bb_tests_cpp/test_table_basic.cpp b/tests/bb_tests_cpp/test_table_basic.cpp index 3aba426..c415ad0 100644 --- a/tests/bb_tests_cpp/test_table_basic.cpp +++ b/tests/bb_tests_cpp/test_table_basic.cpp @@ -1,9 +1,259 @@ #include "tests.h" #include "fort.hpp" +#define assert_string_equal(str1, str2) assert_str_equal(str1.c_str(), str2.c_str()) + +bool set_test_options_for_table(fort::Table *table) +{ + assert_true(table->set_cell_bottom_padding(FT_ANY_ROW, FT_ANY_COLUMN, 1)); + assert_true(table->set_cell_top_padding(FT_ANY_ROW, FT_ANY_COLUMN, 1)); + assert_true(table->set_cell_left_padding(FT_ANY_ROW, FT_ANY_COLUMN, 1)); + assert_true(table->set_cell_right_padding(FT_ANY_ROW, FT_ANY_COLUMN, 1)); + assert_true(table->set_cell_empty_str_height(FT_ANY_ROW, FT_ANY_COLUMN, 1)); + + struct ft_border_style brdr_style; + brdr_style.border_chs.top_border_ch = "-"; + brdr_style.border_chs.separator_ch = "-"; + brdr_style.border_chs.bottom_border_ch = "-"; + brdr_style.border_chs.side_border_ch = "|"; + brdr_style.border_chs.out_intersect_ch = "+"; + brdr_style.border_chs.in_intersect_ch = "+"; + + brdr_style.header_border_chs.top_border_ch = "-"; + brdr_style.header_border_chs.separator_ch = "-"; + brdr_style.header_border_chs.bottom_border_ch = "-"; + brdr_style.header_border_chs.side_border_ch = "|"; + brdr_style.header_border_chs.out_intersect_ch = "+"; + brdr_style.header_border_chs.in_intersect_ch = "+"; + + brdr_style.hor_separator_char = "="; + table->set_border_style(&brdr_style); + + return true; +} + void test_cpp_table_basic(void) { + WHEN("All columns are equal and not empty") { + fort::Table table; + assert_true(set_test_options_for_table(&table)); + table << fort::header + << "3" << "c" << "234" << "3.140000" << fort::endr + << "3" << "c" << "234" << "3.140000" << fort::endr + << "3" << "c" << "234" << "3.140000" << fort::endr; + + std::string table_str = table.to_string(); + std::string table_str_etalon = + "+---+---+-----+----------+\n" + "| | | | |\n" + "| 3 | c | 234 | 3.140000 |\n" + "| | | | |\n" + "+---+---+-----+----------+\n" + "| | | | |\n" + "| 3 | c | 234 | 3.140000 |\n" + "| | | | |\n" + "+---+---+-----+----------+\n" + "| | | | |\n" + "| 3 | c | 234 | 3.140000 |\n" + "| | | | |\n" + "+---+---+-----+----------+\n"; + assert_string_equal(table_str, table_str_etalon); + } + + WHEN("All columns are not equal and not empty") { + fort::Table table; + assert_true(set_test_options_for_table(&table)); + + table << fort::header + << "3" << "c" << "234" << "3.140000" << fort::endr + << "c" << "234" << "3.140000" << "3" << fort::endr + << "234" << "3.140000" << "3" << "c" << fort::endr; + + std::string table_str = table.to_string(); + std::string table_str_etalon = + "+-----+----------+----------+----------+\n" + "| | | | |\n" + "| 3 | c | 234 | 3.140000 |\n" + "| | | | |\n" + "+-----+----------+----------+----------+\n" + "| | | | |\n" + "| c | 234 | 3.140000 | 3 |\n" + "| | | | |\n" + "+-----+----------+----------+----------+\n" + "| | | | |\n" + "| 234 | 3.140000 | 3 | c |\n" + "| | | | |\n" + "+-----+----------+----------+----------+\n"; + assert_string_equal(table_str, table_str_etalon); + } + + WHEN("All columns are not equal and some cells are empty") { + fort::Table table; + assert_true(set_test_options_for_table(&table)); + + table << fort::header + << "" << "" << "234" << "3.140000" << fort::endr + << "c" << "234" << "3.140000" << "" << fort::endr + << "234" << "3.140000" << "" << "" << fort::endr; + + std::string table_str = table.to_string(); + std::string table_str_etalon = + "+-----+----------+----------+----------+\n" + "| | | | |\n" + "| | | 234 | 3.140000 |\n" + "| | | | |\n" + "+-----+----------+----------+----------+\n" + "| | | | |\n" + "| c | 234 | 3.140000 | |\n" + "| | | | |\n" + "+-----+----------+----------+----------+\n" + "| | | | |\n" + "| 234 | 3.140000 | | |\n" + "| | | | |\n" + "+-----+----------+----------+----------+\n"; + assert_string_equal(table_str, table_str_etalon); + } + + WHEN("All cells are empty") { + fort::Table table; + assert_true(set_test_options_for_table(&table)); + + table << fort::header + << "" << "" << "" << "" << fort::endr + << "" << "" << "" << "" << fort::endr + << "" << "" << "" << "" << fort::endr; + + std::string table_str = table.to_string(); + std::string table_str_etalon = + "+--+--+--+--+\n" + "| | | | |\n" + "| | | | |\n" + "| | | | |\n" + "+--+--+--+--+\n" + "| | | | |\n" + "| | | | |\n" + "| | | | |\n" + "+--+--+--+--+\n" + "| | | | |\n" + "| | | | |\n" + "| | | | |\n" + "+--+--+--+--+\n"; + assert_string_equal(table_str, table_str_etalon); + } } +void test_cpp_table_write(void) +{ + SCENARIO("Test write functions") { + fort::Table table; + assert_true(set_test_options_for_table(&table)); + table << fort::header; + assert_true(table.write("3")); + assert_true(table.write("c")); + assert_true(table.write("234")); + assert_true(table.write_ln("3.140000")); + + assert_true(table.write("c")); + assert_true(table.write("235")); + assert_true(table.write("3.150000")); + assert_true(table.write_ln("5")); + + assert_true(table.write("234")); + assert_true(table.write("3.140000")); + assert_true(table.write("3")); + assert_true(table.write_ln("c")); + + /* Replace old values */ + table[1][1] = "234"; + assert_true(table.write("3.140000")); + assert_true(table.write_ln("3")); + + std::string table_str = table.to_string(); + std::string table_str_etalon = + "+-----+----------+----------+----------+\n" + "| | | | |\n" + "| 3 | c | 234 | 3.140000 |\n" + "| | | | |\n" + "+-----+----------+----------+----------+\n" + "| | | | |\n" + "| c | 234 | 3.140000 | 3 |\n" + "| | | | |\n" + "+-----+----------+----------+----------+\n" + "| | | | |\n" + "| 234 | 3.140000 | 3 | c |\n" + "| | | | |\n" + "+-----+----------+----------+----------+\n"; + assert_string_equal(table_str, table_str_etalon); + } + + SCENARIO("Test n write functions") { + fort::Table table; + assert_true(set_test_options_for_table(&table)); + table << fort::header; + assert_true(table.write("3", "c", "234", "3.140000")); + table << fort::endr; + + assert_true(table.write_ln("c", "235", "3.150000", "5")); + assert_true(table.write_ln("234", "3.140000", "3", "c")); + + /* Replace old values */ + table[1][1] = "234"; + assert_true(table.write_ln("3.140000", "3")); + + std::string table_str = table.to_string(); + std::string table_str_etalon = + "+-----+----------+----------+----------+\n" + "| | | | |\n" + "| 3 | c | 234 | 3.140000 |\n" + "| | | | |\n" + "+-----+----------+----------+----------+\n" + "| | | | |\n" + "| c | 234 | 3.140000 | 3 |\n" + "| | | | |\n" + "+-----+----------+----------+----------+\n" + "| | | | |\n" + "| 234 | 3.140000 | 3 | c |\n" + "| | | | |\n" + "+-----+----------+----------+----------+\n"; + assert_string_equal(table_str, table_str_etalon); + } + + SCENARIO("Test row_write functions") { + fort::Table table; + assert_true(set_test_options_for_table(&table)); + + table << fort::header; + const char *row_0[4] = {"3", "c", "234", "3.140000"}; + const char *row_1[4] = {"c", "235", "3.150000", "5"}; + const char *row_2[4] = {"234", "3.140000", "3", "c"}; + assert_true(table.row_write_ln(std::begin(row_0), std::end(row_0))); + assert_true(table.row_write(std::begin(row_1), std::end(row_1))); + table << fort::endr; + assert_true(table.row_write_ln(std::begin(row_2), std::end(row_2))); + + /* Replace old values */ + table[1][1] = "234"; + const char *row_11[3] = {"3.140000", "3"}; + assert_true(table.row_write_ln(std::begin(row_11), std::end(row_11))); + + + std::string table_str = table.to_string(); + std::string table_str_etalon = + "+-----+----------+----------+----------+\n" + "| | | | |\n" + "| 3 | c | 234 | 3.140000 |\n" + "| | | | |\n" + "+-----+----------+----------+----------+\n" + "| | | | |\n" + "| c | 234 | 3.140000 | 3 |\n" + "| | | | |\n" + "+-----+----------+----------+----------+\n" + "| | | | |\n" + "| 234 | 3.140000 | 3 | c |\n" + "| | | | |\n" + "+-----+----------+----------+----------+\n"; + assert_string_equal(table_str, table_str_etalon); + } +} diff --git a/tests/main_test_cpp.cpp b/tests/main_test_cpp.cpp index ccd8159..4daaa3d 100644 --- a/tests/main_test_cpp.cpp +++ b/tests/main_test_cpp.cpp @@ -3,10 +3,12 @@ #include "fort.h" void test_cpp_table_basic(void); +void test_cpp_table_write(void); struct test_case bb_test_suit [] = { {"test_cpp_table_basic", test_cpp_table_basic}, + {"test_cpp_table_write", test_cpp_table_write}, };