From f7914a356c4678c8f3a8ead1fcf146d4130cc1dc Mon Sep 17 00:00:00 2001 From: Stephane Janel Date: Wed, 23 Aug 2023 18:18:53 +0200 Subject: [PATCH] Slightly improved SimpleTable pretty print with '+' instead of '-' at intersection of columns --- src/engine/src/queryresultprinter.cpp | 3 +- .../test/queryresultprinter_private_test.cpp | 96 +++++++++---------- .../test/queryresultprinter_public_test.cpp | 78 +++++++-------- src/tech/include/simpletable.hpp | 13 ++- src/tech/src/simpletable.cpp | 49 ++++++---- src/tech/test/simpletable_test.cpp | 12 ++- 6 files changed, 140 insertions(+), 111 deletions(-) diff --git a/src/engine/src/queryresultprinter.cpp b/src/engine/src/queryresultprinter.cpp index 7ce175b5..985bbee2 100644 --- a/src/engine/src/queryresultprinter.cpp +++ b/src/engine/src/queryresultprinter.cpp @@ -1071,7 +1071,8 @@ void QueryResultPrinter::printDustSweeper( void QueryResultPrinter::printTable(const SimpleTable &simpleTable) const { std::ostringstream ss; std::ostream &os = _pOs != nullptr ? *_pOs : ss; - simpleTable.print(os); + + os << simpleTable; if (_pOs != nullptr) { *_pOs << std::endl; diff --git a/src/engine/test/queryresultprinter_private_test.cpp b/src/engine/test/queryresultprinter_private_test.cpp index f9f57772..27d1048b 100644 --- a/src/engine/test/queryresultprinter_private_test.cpp +++ b/src/engine/test/queryresultprinter_private_test.cpp @@ -16,9 +16,9 @@ class QueryResultPrinterEmptyBalanceNoEquiCurTest : public QueryResultPrinterTes TEST_F(QueryResultPrinterEmptyBalanceNoEquiCurTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable).printBalance(balancePerExchange, equiCur); static constexpr std::string_view kExpected = R"( ------------------------------------------------------------------------------ ++----------+--------------------------+-------------------+-----------------+ | Currency | Total amount on selected | binance_testuser1 | huobi_testuser2 | ------------------------------------------------------------------------------ ++----------+--------------------------+-------------------+-----------------+ )"; expectStr(kExpected); } @@ -82,9 +82,9 @@ class QueryResultPrinterBalanceNoEquiCurTest : public QueryResultPrinterTest { TEST_F(QueryResultPrinterBalanceNoEquiCurTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable).printBalance(balancePerExchange, equiCur); static constexpr std::string_view kExpected = R"( -------------------------------------------------------------------------------------------------- ++----------+--------------------------+-------------------+-----------------+-------------------+ | Currency | Total amount on selected | binance_testuser1 | huobi_testuser2 | bithumb_testuser1 | -------------------------------------------------------------------------------------------------- ++----------+--------------------------+-------------------+-----------------+-------------------+ | ADA | 147 | 0 | 147 | 0 | | BTC | 15 | 15 | 0 | 0 | | DOT | 4.76 | 0 | 4.76 | 0 | @@ -94,7 +94,7 @@ TEST_F(QueryResultPrinterBalanceNoEquiCurTest, FormattedTable) { | USD | 155 | 0 | 155 | 0 | | USDT | 5107.5 | 5000 | 107.5 | 0 | | XRP | 1500 | 1500 | 0 | 0 | -------------------------------------------------------------------------------------------------- ++----------+--------------------------+-------------------+-----------------+-------------------+ )"; expectStr(kExpected); } @@ -225,17 +225,17 @@ class QueryResultPrinterBalanceEquiCurTest : public QueryResultPrinterTest { TEST_F(QueryResultPrinterBalanceEquiCurTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable).printBalance(balancePerExchange, equiCur); static constexpr std::string_view kExpected = R"( ----------------------------------------------------------------------------------------------------------------------------------- ++----------+--------------------------+--------------+-------------------+-----------------+-------------------+-----------------+ | Currency | Total amount on selected | Total EUR eq | binance_testuser1 | huobi_testuser2 | bithumb_testuser1 | huobi_testuser1 | ----------------------------------------------------------------------------------------------------------------------------------- ++----------+--------------------------+--------------+-------------------+-----------------+-------------------+-----------------+ | ETH | 15 | 25000 | 0 | 15 | 0 | 0 | | ADA | 15000 | 10000 | 15000 | 0 | 0 | 0 | | BTC | 0.56 | 9067.7 | 0.56 | 0 | 0 | 0 | | XLM | 123 | 67.5 | 0 | 123 | 0 | 0 | | XRP | 34.7 | 45.08 | 0 | 34.7 | 0 | 0 | ----------------------------------------------------------------------------------------------------------------------------------- ++----------+--------------------------+--------------+-------------------+-----------------+-------------------+-----------------+ | Total | | 44180.28 | | | | | ----------------------------------------------------------------------------------------------------------------------------------- ++----------+--------------------------+--------------+-------------------+-----------------+-------------------+-----------------+ )"; expectStr(kExpected); } @@ -354,12 +354,12 @@ class QueryResultPrinterDepositInfoWithoutTagTest : public QueryResultPrinterTes TEST_F(QueryResultPrinterDepositInfoWithoutTagTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable).printDepositInfo(depositCurrencyCode, walletPerExchange); static constexpr std::string_view kExpected = R"( ----------------------------------------------------------- ++----------+-----------+---------------+-----------------+ | Exchange | Account | ETH address | Destination Tag | ----------------------------------------------------------- ++----------+-----------+---------------+-----------------+ | bithumb | testuser1 | ethaddress666 | | | huobi | testuser2 | ethaddress667 | | ----------------------------------------------------------- ++----------+-----------+---------------+-----------------+ )"; expectStr(kExpected); @@ -424,12 +424,12 @@ class QueryResultPrinterDepositInfoWithTagTest : public QueryResultPrinterTest { TEST_F(QueryResultPrinterDepositInfoWithTagTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable).printDepositInfo(depositCurrencyCode, walletPerExchange); static constexpr std::string_view kExpected = R"( ----------------------------------------------------------- ++----------+-----------+---------------+-----------------+ | Exchange | Account | XRP address | Destination Tag | ----------------------------------------------------------- ++----------+-----------+---------------+-----------------+ | huobi | testuser1 | xrpaddress666 | xrptag1 | | huobi | testuser2 | xrpaddress666 | xrptag2 | ----------------------------------------------------------- ++----------+-----------+---------------+-----------------+ )"; expectStr(kExpected); } @@ -496,13 +496,13 @@ TEST_F(QueryResultPrinterTradesAmountTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable) .printTrades(tradedAmountsPerExchange, startAmount, isPercentageTrade, toCurrency, tradeOptions); static constexpr std::string_view kExpected = R"( ------------------------------------------------------------------------------- ++----------+-----------+---------------------------+-------------------------+ | Exchange | Account | Traded from amount (real) | Traded to amount (real) | ------------------------------------------------------------------------------- ++----------+-----------+---------------------------+-------------------------+ | binance | testuser1 | 0.1 BTC | 1050 XRP | | huobi | testuser1 | 0.3 BTC | 3500.6 XRP | | huobi | testuser2 | 0 BTC | 0 XRP | ------------------------------------------------------------------------------- ++----------+-----------+---------------------------+-------------------------+ )"; expectStr(kExpected); @@ -611,11 +611,11 @@ TEST_F(QueryResultPrinterTradesPercentageTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable) .printTrades(tradedAmountsPerExchange, startAmount, isPercentageTrade, toCurrency, tradeOptions); static constexpr std::string_view kExpected = R"( ------------------------------------------------------------------------------- ++----------+-----------+---------------------------+-------------------------+ | Exchange | Account | Traded from amount (real) | Traded to amount (real) | ------------------------------------------------------------------------------- ++----------+-----------+---------------------------+-------------------------+ | bithumb | testuser1 | 15000.56 EUR | 885475102 SHIB | ------------------------------------------------------------------------------- ++----------+-----------+---------------------------+-------------------------+ )"; expectStr(kExpected); } @@ -711,11 +711,11 @@ TEST_F(QueryResultPrinterSmartBuyTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable) .printBuyTrades(tradedAmountsPerExchange, endAmount, tradeOptions); static constexpr std::string_view kExpected = R"( ------------------------------------------------------------------------------- ++----------+-----------+---------------------------+-------------------------+ | Exchange | Account | Traded from amount (real) | Traded to amount (real) | ------------------------------------------------------------------------------- ++----------+-----------+---------------------------+-------------------------+ | binance | testuser1 | 4500.67 EUR | 3 ETH | ------------------------------------------------------------------------------- ++----------+-----------+---------------------------+-------------------------+ )"; expectStr(kExpected); } @@ -805,13 +805,13 @@ TEST_F(QueryResultPrinterSmartSellTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable) .printSellTrades(tradedAmountsPerExchange, startAmount, isPercentageTrade, tradeOptions); static constexpr std::string_view kExpected = R"( ------------------------------------------------------------------------------- ++----------+-----------+---------------------------+-------------------------+ | Exchange | Account | Traded from amount (real) | Traded to amount (real) | ------------------------------------------------------------------------------- ++----------+-----------+---------------------------+-------------------------+ | binance | testuser1 | 0.01 BTC | 1500 USDT | | huobi | testuser1 | 0.004 BTC | 350 EUR | | huobi | testuser2 | 0.1 BTC | 17 ETH | ------------------------------------------------------------------------------- ++----------+-----------+---------------------------+-------------------------+ )"; expectStr(kExpected); @@ -930,15 +930,15 @@ class QueryResultPrinterOpenedOrdersNoConstraintsTest : public QueryResultPrinte TEST_F(QueryResultPrinterOpenedOrdersNoConstraintsTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable).printOpenedOrders(openedOrdersPerExchange, ordersConstraints); static constexpr std::string_view kExpected = R"( ---------------------------------------------------------------------------------------------------------------------------- ++----------+-----------+-------------+---------------------+------+-----------------+------------------+------------------+ | Exchange | Account | Exchange Id | Placed time | Side | Price | Matched Amount | Remaining Amount | ---------------------------------------------------------------------------------------------------------------------------- ++----------+-----------+-------------+---------------------+------+-----------------+------------------+------------------+ | bithumb | testuser1 | id5 | 2002-06-23 07:58:35 | Sell | 0.00000045 USDT | 11235435435 SHIB | 11235435.59 SHIB | | bithumb | testuser1 | id3 | 2006-07-14 23:58:24 | Buy | 1.31 USDT | 13 XRP | 500.45 XRP | | huobi | testuser2 | id2 | 2002-06-23 07:58:35 | Sell | 1500.56 USDT | 0.56 ETH | 0.44 ETH | | huobi | testuser1 | id1 | 1999-03-25 04:46:43 | Buy | 50000 EUR | 0 BTC | 1 BTC | | huobi | testuser1 | id4 | 2011-10-03 06:49:36 | Sell | 1574564 KRW | 34.56 LTC | 0.4 LTC | ---------------------------------------------------------------------------------------------------------------------------- ++----------+-----------+-------------+---------------------+------+-----------------+------------------+------------------+ )"; expectStr(kExpected); } @@ -1052,15 +1052,15 @@ class QueryResultPrinterRecentDepositsNoConstraintsTest : public QueryResultPrin TEST_F(QueryResultPrinterRecentDepositsNoConstraintsTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable).printRecentDeposits(depositsPerExchange, constraints); static constexpr std::string_view kExpected = R"( -------------------------------------------------------------------------------------------- ++----------+-----------+-------------+---------------------+-----------------+------------+ | Exchange | Account | Exchange Id | Received time | Amount | Status | -------------------------------------------------------------------------------------------- ++----------+-----------+-------------+---------------------+-----------------+------------+ | bithumb | testuser1 | id3 | 2006-07-14 23:58:24 | 15020.67 EUR | failed | | bithumb | testuser1 | id5 | 2011-10-03 06:49:36 | 69204866.9 DOGE | success | | huobi | testuser2 | id2 | 2002-06-23 07:58:35 | 37 XRP | success | | huobi | testuser1 | id1 | 1999-03-25 04:46:43 | 0.045 BTC | initial | | huobi | testuser1 | id4 | 2011-10-03 06:49:36 | 1.31 ETH | processing | -------------------------------------------------------------------------------------------- ++----------+-----------+-------------+---------------------+-----------------+------------+ )"; expectStr(kExpected); } @@ -1168,15 +1168,15 @@ class QueryResultPrinterRecentWithdrawsNoConstraintsTest : public QueryResultPri TEST_F(QueryResultPrinterRecentWithdrawsNoConstraintsTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable).printRecentWithdraws(withdrawsPerExchange, constraints); static constexpr std::string_view kExpected = R"( ------------------------------------------------------------------------------------------------------------- ++----------+-----------+-------------+---------------------+--------------------+-------------+------------+ | Exchange | Account | Exchange Id | Sent time | Net Emitted Amount | Fee | Status | ------------------------------------------------------------------------------------------------------------- ++----------+-----------+-------------+---------------------+--------------------+-------------+------------+ | bithumb | testuser1 | id3 | 1999-03-25 04:46:43 | 15020.67 EUR | 0.1 EUR | failed | | bithumb | testuser1 | id5 | 2002-06-23 07:58:35 | 69204866.9 DOGE | 2 DOGE | success | | huobi | testuser2 | id2 | 2011-10-03 06:49:36 | 37 XRP | 0.02 XRP | success | | huobi | testuser1 | id4 | 2002-06-23 07:58:35 | 1.31 ETH | 0.001 ETH | processing | | huobi | testuser1 | id1 | 2006-07-14 23:58:24 | 0.045 BTC | 0.00001 BTC | initial | ------------------------------------------------------------------------------------------------------------- ++----------+-----------+-------------+---------------------+--------------------+-------------+------------+ )"; expectStr(kExpected); } @@ -1276,14 +1276,14 @@ TEST_F(QueryResultPrinterCancelOrdersTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable) .printCancelledOrders(nbCancelledOrdersPerExchange, ordersConstraints); static constexpr std::string_view kExpected = R"( ------------------------------------------------------ ++----------+-----------+----------------------------+ | Exchange | Account | Number of cancelled orders | ------------------------------------------------------ ++----------+-----------+----------------------------+ | binance | testuser1 | 2 | | bithumb | testuser1 | 3 | | huobi | testuser2 | 1 | | huobi | testuser1 | 17 | ------------------------------------------------------ ++----------+-----------+----------------------------+ )"; expectStr(kExpected); } @@ -1366,11 +1366,11 @@ TEST_F(QueryResultPrinterWithdrawAmountTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable) .printWithdraw(deliveredWithdrawInfoWithExchanges, isPercentageWithdraw, withdrawOptions); static constexpr std::string_view kExpected = R"( ------------------------------------------------------------------------------------------------------------------------------------------------------ ++---------------+--------------+-----------------------+---------------------+-------------+------------+---------------------+---------------------+ | From Exchange | From Account | Gross withdraw amount | Initiated time | To Exchange | To Account | Net received amount | Received time | ------------------------------------------------------------------------------------------------------------------------------------------------------ ++---------------+--------------+-----------------------+---------------------+-------------+------------+---------------------+---------------------+ | binance | testuser1 | 76.55 XRP | 1999-03-25 04:46:43 | huobi | testuser2 | 75.55 XRP | 2002-06-23 07:58:35 | ------------------------------------------------------------------------------------------------------------------------------------------------------ ++---------------+--------------+-----------------------+---------------------+-------------+------------+---------------------+---------------------+ )"; expectStr(kExpected); } @@ -1423,11 +1423,11 @@ TEST_F(QueryResultPrinterWithdrawPercentageTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable) .printWithdraw(deliveredWithdrawInfoWithExchanges, isPercentageWithdraw, withdrawOptions); static constexpr std::string_view kExpected = R"( ------------------------------------------------------------------------------------------------------------------------------------------------------ ++---------------+--------------+-----------------------+---------------------+-------------+------------+---------------------+---------------------+ | From Exchange | From Account | Gross withdraw amount | Initiated time | To Exchange | To Account | Net received amount | Received time | ------------------------------------------------------------------------------------------------------------------------------------------------------ ++---------------+--------------+-----------------------+---------------------+-------------+------------+---------------------+---------------------+ | binance | testuser1 | 76.55 XRP | 1999-03-25 04:46:43 | huobi | testuser2 | 75.55 XRP | 2002-06-23 07:58:35 | ------------------------------------------------------------------------------------------------------------------------------------------------------ ++---------------+--------------+-----------------------+---------------------+-------------+------------+---------------------+---------------------+ )"; expectStr(kExpected); } @@ -1491,13 +1491,13 @@ TEST_F(QueryResultPrinterDustSweeperTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable) .printDustSweeper(tradedAmountsVectorWithFinalAmountPerExchange, cur); static constexpr std::string_view kExpected = R"( ------------------------------------------------------------------------------------------------ ++----------+-----------+-------------------------------------------------------+--------------+ | Exchange | Account | Trades | Final Amount | ------------------------------------------------------------------------------------------------ ++----------+-----------+-------------------------------------------------------+--------------+ | binance | testuser1 | 98.47 ETH -> 0.00005 BTC | 0 ETH | | huobi | testuser1 | | 1.56 ETH | | huobi | testuser2 | 0.45609 EUR -> 98.47 ETH, 1509.45 ETH -> 0.000612 BTC | 0 ETH | ------------------------------------------------------------------------------------------------ ++----------+-----------+-------------------------------------------------------+--------------+ )"; expectStr(kExpected); } diff --git a/src/engine/test/queryresultprinter_public_test.cpp b/src/engine/test/queryresultprinter_public_test.cpp index 524afd1b..c234380f 100644 --- a/src/engine/test/queryresultprinter_public_test.cpp +++ b/src/engine/test/queryresultprinter_public_test.cpp @@ -13,12 +13,12 @@ class QueryResultPrinterHealthCheckTest : public QueryResultPrinterTest { TEST_F(QueryResultPrinterHealthCheckTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable).printHealthCheck(healthCheckPerExchange); static constexpr std::string_view kExpected = R"( ----------------------------------- ++----------+---------------------+ | Exchange | Health Check status | ----------------------------------- ++----------+---------------------+ | binance | OK | | huobi | Not OK! | ----------------------------------- ++----------+---------------------+ )"; expectStr(kExpected); @@ -67,13 +67,13 @@ class QueryResultPrinterMarketsTest : public QueryResultPrinterTest { TEST_F(QueryResultPrinterMarketsTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable).printMarkets(cur1, cur2, marketsPerExchange); static constexpr std::string_view kExpected = R"( -------------------------------- ++----------+------------------+ | Exchange | Markets with XRP | -------------------------------- ++----------+------------------+ | binance | XRP-BTC | | binance | XRP-KRW | | huobi | XRP-EUR | -------------------------------- ++----------+------------------+ )"; expectStr(kExpected); @@ -133,13 +133,13 @@ class QueryResultPrinterTickerTest : public QueryResultPrinterTest { TEST_F(QueryResultPrinterTickerTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable).printTickerInformation(exchangeTickerMaps); static constexpr std::string_view kExpected = R"( ------------------------------------------------------------------------------- ++----------+---------+--------------+------------+--------------+------------+ | Exchange | Market | Bid price | Bid volume | Ask price | Ask volume | ------------------------------------------------------------------------------- ++----------+---------+--------------+------------+--------------+------------+ | bithumb | ETH-EUR | 2301.05 EUR | 17 ETH | 2301.15 EUR | 0.4 ETH | | huobi | BTC-EUR | 31051.01 EUR | 1.9087 BTC | 31051.02 EUR | 0.409 BTC | | huobi | XRP-BTC | 0.36 BTC | 3494 XRP | 0.37 BTC | 916.4 XRP | ------------------------------------------------------------------------------- ++----------+---------+--------------+------------+--------------+------------+ )"; expectStr(kExpected); } @@ -223,26 +223,26 @@ TEST_F(QueryResultPrinterMarketOrderBookTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable) .printMarketOrderBooks(mk, CurrencyCode{}, d, marketOrderBookConversionRates); static constexpr std::string_view kExpected = R"( ------------------------------------------------------------------------------ ++-----------------------+----------------------------+----------------------+ | Sellers of BTC (asks) | exchangeA BTC price in EUR | Buyers of BTC (bids) | ------------------------------------------------------------------------------ ++-----------------------+----------------------------+----------------------+ | 0.18116 | 31056.7 | | | 0.15058 | 31056.68 | | | 0.12 | 31056.67 | | | | 31056.66 | 0.00234 | | | 31056.65 | 0.03292 | | | 31056.63 | 0.0635 | ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ ++-----------------------+----------------------------+----------------------+ ++-----------------------+----------------------------+----------------------+ | Sellers of BTC (asks) | exchangeD BTC price in EUR | Buyers of BTC (bids) | ------------------------------------------------------------------------------ ++-----------------------+----------------------------+----------------------+ | 0.18116 | 31056.7 | | | 0.15058 | 31056.68 | | | 0.12 | 31056.67 | | | | 31056.66 | 0.00234 | | | 31056.65 | 0.03292 | | | 31056.63 | 0.0635 | ------------------------------------------------------------------------------ ++-----------------------+----------------------------+----------------------+ )"; expectStr(kExpected); } @@ -360,12 +360,12 @@ class QueryResultPrinterConversionPathTest : public QueryResultPrinterTest { TEST_F(QueryResultPrinterConversionPathTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable).printConversionPath(marketForPath, conversionPathPerExchange); static constexpr std::string_view kExpected = R"( --------------------------------------------------- ++----------+-------------------------------------+ | Exchange | Fastest conversion path for XLM-XRP | --------------------------------------------------- ++----------+-------------------------------------+ | bithumb | XLM-XRP | | huobi | XLM-AAA,BBB-AAA,BBB-XRP | --------------------------------------------------- ++----------+-------------------------------------+ )"; expectStr(kExpected); } @@ -424,12 +424,12 @@ class QueryResultPrinterWithdrawFeeTest : public QueryResultPrinterTest { TEST_F(QueryResultPrinterWithdrawFeeTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable).printWithdrawFees(withdrawFeePerExchange, curWithdrawFee); static constexpr std::string_view kExpected = R"( ---------------------------- ++----------+--------------+ | Exchange | Withdraw fee | ---------------------------- ++----------+--------------+ | bithumb | 0.15 ETH | | huobi | 0.05 ETH | ---------------------------- ++----------+--------------+ )"; expectStr(kExpected); } @@ -483,12 +483,12 @@ TEST_F(QueryResultPrinterLast24HoursTradedVolumeTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable) .printLast24hTradedVolume(marketLast24hTradedVolume, monetaryAmountPerExchange); static constexpr std::string_view kExpected = R"( ---------------------------------------------- ++----------+--------------------------------+ | Exchange | Last 24h BTC-EUR traded volume | ---------------------------------------------- ++----------+--------------------------------+ | binance | 37.8 BTC | | huobi | 14 BTC | ---------------------------------------------- ++----------+--------------------------------+ )"; expectStr(kExpected); } @@ -559,32 +559,32 @@ TEST_F(QueryResultPrinterLastTradesVolumeTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable) .printLastTrades(marketLastTrades, nbLastTrades, lastTradesPerExchange); static constexpr std::string_view kExpected = R"( --------------------------------------------------------------------------------------------- ++----------------------+--------------------+--------------------------+-------------------+ | binance trades - UTC | ETH buys | Price in USDT | ETH sells | --------------------------------------------------------------------------------------------- ++----------------------+--------------------+--------------------------+-------------------+ | 1999-03-25 04:46:43 | 0.13 | 1500.5 | | | 2002-06-23 07:58:35 | | 1500.5 | 3.7 | | 2006-07-14 23:58:24 | 0.004 | 1501 | | --------------------------------------------------------------------------------------------- ++----------------------+--------------------+--------------------------+-------------------+ | Summary | 0.134 ETH (2 buys) | 1500.66666666666666 USDT | 3.7 ETH (1 sells) | --------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------- ++----------------------+--------------------+--------------------------+-------------------+ ++---------------------+--------------------+---------------+--------------------+ | huobi trades - UTC | ETH buys | Price in USDT | ETH sells | ---------------------------------------------------------------------------------- ++---------------------+--------------------+---------------+--------------------+ | 2011-10-03 06:49:36 | | 1500.5 | 0.13 | | 2002-06-23 07:58:35 | 0.004 | 1501 | | ---------------------------------------------------------------------------------- ++---------------------+--------------------+---------------+--------------------+ | Summary | 0.004 ETH (1 buys) | 1500.75 USDT | 0.13 ETH (1 sells) | ---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------- ++---------------------+--------------------+---------------+--------------------+ ++----------------------+---------------------+--------------------------+--------------------+ | bithumb trades - UTC | ETH buys | Price in USDT | ETH sells | ----------------------------------------------------------------------------------------------- ++----------------------+---------------------+--------------------------+--------------------+ | 2011-10-03 06:49:36 | | 1500.5 | 0.13 | | 2002-06-23 07:58:35 | 0.004 | 1501 | | | 1999-03-25 04:46:43 | 47.78 | 1498 | | ----------------------------------------------------------------------------------------------- ++----------------------+---------------------+--------------------------+--------------------+ | Summary | 47.784 ETH (2 buys) | 1499.83333333333333 USDT | 0.13 ETH (1 sells) | ----------------------------------------------------------------------------------------------- ++----------------------+---------------------+--------------------------+--------------------+ )"; expectStr(kExpected); } @@ -694,13 +694,13 @@ class QueryResultPrinterLastPriceTest : public QueryResultPrinterTest { TEST_F(QueryResultPrinterLastPriceTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::kFormattedTable).printLastPrice(marketLastPrice, monetaryAmountPerExchange); static constexpr std::string_view kExpected = R"( ---------------------------------- ++----------+--------------------+ | Exchange | XRP-KRW last price | ---------------------------------- ++----------+--------------------+ | binance | 417 KRW | | huobi | 444 KRW | | bithumb | 590 KRW | ---------------------------------- ++----------+--------------------+ )"; expectStr(kExpected); } diff --git a/src/tech/include/simpletable.hpp b/src/tech/include/simpletable.hpp index ea7bbf07..6ca1d665 100644 --- a/src/tech/include/simpletable.hpp +++ b/src/tech/include/simpletable.hpp @@ -11,6 +11,7 @@ #include #endif +#include "cct_smallvector.hpp" #include "cct_string.hpp" #include "cct_type_traits.hpp" #include "cct_vector.hpp" @@ -120,11 +121,11 @@ class SimpleTable { bool operator==(const Row &) const = default; - // TODO: to be replaced by spaceship defaulted operator once vector supports it - bool operator<(const Row &o) const { return _cells < o._cells; } + auto operator<=>(const Row &) const = default; private: friend class SimpleTable; + friend std::ostream &operator<<(std::ostream &, const SimpleTable &); void print(std::ostream &os, std::span maxWidthPerColumn) const; @@ -167,11 +168,17 @@ class SimpleTable { void reserve(size_type s) { _rows.reserve(s); } - void print(std::ostream &os = std::cout) const; + friend std::ostream &operator<<(std::ostream &os, const SimpleTable &t); using trivially_relocatable = is_trivially_relocatable>::type; private: + using MaxWidthPerColumnVector = SmallVector; + + MaxWidthPerColumnVector computeMaxWidthPerColumn() const; + + Cell::string_type computeLineSep(std::span maxWidthPerColumnVector) const; + vector _rows; }; } // namespace cct \ No newline at end of file diff --git a/src/tech/src/simpletable.cpp b/src/tech/src/simpletable.cpp index 05a16056..0f51a13d 100644 --- a/src/tech/src/simpletable.cpp +++ b/src/tech/src/simpletable.cpp @@ -5,7 +5,6 @@ #include #include -#include "cct_smallvector.hpp" #include "mathhelpers.hpp" #include "unreachable.hpp" @@ -17,7 +16,6 @@ const SimpleTable::Row SimpleTable::Row::kDivider; namespace { constexpr char kColumnSep = '|'; -constexpr char kLineSep = '-'; enum class AlignTo : int8_t { kLeft, kRight }; @@ -76,33 +74,52 @@ void SimpleTable::Row::print(std::ostream &os, std::span maxWidt os << std::endl; } -void SimpleTable::print(std::ostream &os) const { - if (_rows.empty()) { - return; - } +SimpleTable::MaxWidthPerColumnVector SimpleTable::computeMaxWidthPerColumn() const { // We assume that each row has same number of cells, no silly checks here const size_type nbColumns = _rows.front().size(); - SmallVector maxWidthPerColumn(nbColumns, 0); + MaxWidthPerColumnVector res(nbColumns, 0); for (const Row &row : _rows) { if (!row.isDivider()) { for (size_type columnPos = 0; columnPos < nbColumns; ++columnPos) { - maxWidthPerColumn[columnPos] = - std::max(maxWidthPerColumn[columnPos], static_cast(row[columnPos].size())); + res[columnPos] = std::max(res[columnPos], static_cast(row[columnPos].size())); } } } - const size_type sumWidths = std::accumulate(maxWidthPerColumn.begin(), maxWidthPerColumn.end(), 0U); - const size_type maxTableWidth = sumWidths + nbColumns * 3 + 1; - const Cell::string_type lineSep(maxTableWidth, kLineSep); + return res; +} + +SimpleTable::Cell::string_type SimpleTable::computeLineSep(std::span maxWidthPerColumnVector) const { + const size_type sumWidths = std::accumulate(maxWidthPerColumnVector.begin(), maxWidthPerColumnVector.end(), 0U); + + // 3 as one space before, one space after the field name and column separator. +1 for the first column separator + const size_type tableWidth = sumWidths + maxWidthPerColumnVector.size() * 3 + 1; + Cell::string_type lineSep(tableWidth, '-'); + + size_type curWidth = 0; + lineSep[curWidth] = '+'; + for (auto maxWidth : maxWidthPerColumnVector) { + curWidth += maxWidth + 3; + lineSep[curWidth] = '+'; + } + + return lineSep; +} + +std::ostream &operator<<(std::ostream &os, const SimpleTable &t) { + if (t._rows.empty()) { + return os; + } + const auto maxWidthPerColumnVector = t.computeMaxWidthPerColumn(); + const auto lineSep = t.computeLineSep(maxWidthPerColumnVector); os << lineSep << std::endl; - bool printHeader = _rows.size() > 1U; - for (const Row &row : _rows) { + bool printHeader = t._rows.size() > 1U; + for (const auto &row : t._rows) { if (row.isDivider()) { os << lineSep << std::endl; } else { - row.print(os, maxWidthPerColumn); + row.print(os, maxWidthPerColumnVector); } if (printHeader) { os << lineSep << std::endl; @@ -110,6 +127,6 @@ void SimpleTable::print(std::ostream &os) const { } } - os << lineSep; + return os << lineSep; } } // namespace cct \ No newline at end of file diff --git a/src/tech/test/simpletable_test.cpp b/src/tech/test/simpletable_test.cpp index 107fe0ba..33edc111 100644 --- a/src/tech/test/simpletable_test.cpp +++ b/src/tech/test/simpletable_test.cpp @@ -6,7 +6,8 @@ namespace cct { TEST(SimpleTable, DefaultConstructor) { SimpleTable table; EXPECT_TRUE(table.empty()); - table.print(std::cout); + + std::cout << table; } TEST(SimpleTable, OneLinePrint) { @@ -14,7 +15,8 @@ TEST(SimpleTable, OneLinePrint) { string str("I am a string"); table.emplace_back("Header 1", 42, std::move(str)); EXPECT_EQ(table.size(), 1U); - table.print(std::cout); + + std::cout << table; } TEST(SimpleTable, SimplePrint) { @@ -32,7 +34,8 @@ TEST(SimpleTable, SimplePrint) { row3.emplace_back("BTC"); table.push_back(std::move(row3)); EXPECT_EQ(table.size(), 3U); - table.print(std::cout); + + std::cout << table; } TEST(SimpleTable, SettingRowDirectly) { @@ -44,6 +47,7 @@ TEST(SimpleTable, SettingRowDirectly) { table.emplace_back(-677256340000, "KEBAB", "-34.09"); EXPECT_EQ(table[2].front().size(), 7U); EXPECT_EQ(table.back().front().size(), 13U); - table.print(std::cout); + + std::cout << table; } } // namespace cct \ No newline at end of file