@@ -45,7 +45,11 @@ extern "C" {
4545#include < nlohmann/json.hpp>
4646#include " spdlog/spdlog.h"
4747#include < fmt/ranges.h>
48- #include " lvgl/lvgl.h"
48+ #include " ../lvgl/lvgl.h"
49+
50+ #ifdef BUILD_TESTS
51+ #include < catch2/catch.hpp>
52+ #endif
4953
5054#define WFB_LINK_LOST 1
5155#define WFB_LINK_JAMMED 2
@@ -464,7 +468,7 @@ class Fact {
464468 return " (unknown)" ;
465469 }
466470
467- std::string asVerboseString () {
471+ std::string asVerboseString () const {
468472 std::ostringstream oss;
469473 if (!isDefined ()) {
470474 oss << " undef" ;
@@ -501,7 +505,7 @@ class Fact {
501505 void assertType (Type t) const {
502506 if (t != type) {
503507 spdlog::error (" '{}': requested type of {}, but the actual type is {}" ,
504- meta. getName (), typeName (t), typeName (type));
508+ asVerboseString (), typeName (t), typeName (type));
505509 assert (type == t);
506510 }
507511 }
@@ -762,7 +766,8 @@ class Widget {
762766 virtual void draw (cairo_t *cr) {};
763767
764768 virtual void setFact (uint idx, Fact fact) {
765- args[idx] = fact;
769+ if (idx >= args.size ()) throw std::out_of_range (" setFact index out of range" );
770+ args[idx] = fact;
766771 }
767772
768773 int x (cairo_t *cr) {
@@ -840,6 +845,10 @@ class TplTextWidget: public Widget {
840845 cairo_show_text (cr, msg->c_str ());
841846 }
842847
848+ std::unique_ptr<std::string> render_tpl () {
849+ return render_tokens (_tokens, args);
850+ }
851+
843852 uint default_precision = 2 ;
844853
845854protected:
@@ -865,10 +874,6 @@ class TplTextWidget: public Widget {
865874 : type(t), value(std::nullopt ), precision(0 ) {}
866875 };
867876
868- std::unique_ptr<std::string> render_tpl () {
869- return render_tokens (_tokens, args);
870- }
871-
872877 std::unique_ptr<std::string> render_tpl (const std::string& tpl, const std::vector<Fact>& facts) {
873878 auto tokens = tokenize (tpl);
874879 return render_tokens (tokens, facts);
@@ -922,7 +927,7 @@ class TplTextWidget: public Widget {
922927 if (match == " %%" ) {
923928 tokens.emplace_back (TokenType::Literal, " %" );
924929 } else if (match[0 ] == ' %' ) {
925- if (match.size () == 2 ) { // Simple placeholder like %b, %i, %u, %s
930+ if (match.size () == 2 ) { // Simple placeholder like %b, %i, %u, %s, %f
926931 if (match[1 ] == ' b' ) {
927932 tokens.emplace_back (TokenType::Bool);
928933 } else if (match[1 ] == ' i' || match[1 ] == ' d' ) {
@@ -931,8 +936,10 @@ class TplTextWidget: public Widget {
931936 tokens.emplace_back (TokenType::Uint);
932937 } else if (match[1 ] == ' s' ) {
933938 tokens.emplace_back (TokenType::String);
939+ } else if (match[1 ] == ' f' ) {
940+ tokens.emplace_back (TokenType::Float, default_precision);
934941 }
935- } else if (match.back () == ' f' ) { // Float placeholder
942+ } else if (match.back () == ' f' ) { // Float placeholder with precision
936943 uint precision = 0 ;
937944 if (match.size () > 2 && match[1 ] == ' .' ) {
938945 precision = std::stoi (match.substr (2 , match.size () - 3 )); // Extract precision
@@ -1864,8 +1871,6 @@ void modeset_paint_buffer(struct modeset_buf *buf, Osd *osd) {
18641871 unsigned int j,k,off;
18651872 cairo_t * cr;
18661873 cairo_surface_t *surface;
1867- char msg[80 ];
1868- memset (msg, 0x00 , sizeof (msg));
18691874
18701875 int osd_x = buf->width - 300 ;
18711876 surface = cairo_image_surface_create_for_data (buf->map , CAIRO_FORMAT_ARGB32, buf->width , buf->height , buf->stride );
@@ -2180,3 +2185,72 @@ void osd_publish_str_fact(char const *name, osd_tag *tags, int n_tags, const cha
21802185#ifdef __cplusplus
21812186}
21822187#endif
2188+
2189+
2190+ //
2191+ // Code below is only for unit-tests!
2192+ //
2193+ #ifdef TEST
2194+
2195+ TestExpressionTree::TestExpressionTree () {
2196+ tree = new ExpressionTree ();
2197+ }
2198+
2199+ TestExpressionTree::TestExpressionTree (const std::string& expression) {
2200+ tree = new ExpressionTree (expression);
2201+ }
2202+
2203+ TestExpressionTree::~TestExpressionTree () {
2204+ delete tree;
2205+ }
2206+
2207+ std::vector<std::string> TestExpressionTree::tokenize (const std::string& input) {
2208+ return tree->tokenize (input);
2209+ }
2210+
2211+ void TestExpressionTree::parse (const std::string &expression) {
2212+ tree->parse (expression);
2213+ }
2214+
2215+ double TestExpressionTree::evaluate (double xValue) {
2216+ return tree->evaluate (xValue);
2217+ }
2218+
2219+
2220+
2221+ TestTplTextWidget::TestTplTextWidget (int pos_x, int pos_y, std::string tpl, uint n_args) {
2222+ widget = new TplTextWidget (pos_x, pos_y, tpl, n_args);
2223+ }
2224+ TestTplTextWidget::~TestTplTextWidget () {
2225+ delete widget;
2226+ }
2227+ void TestTplTextWidget::setBoolFact (uint idx, bool v) {
2228+ Fact fact = Fact (FactMeta (" bool" ), v);
2229+ widget->setFact (idx, fact);
2230+ };
2231+ void TestTplTextWidget::setLongFact (uint idx, long v) {
2232+ Fact fact = Fact (FactMeta (" long" ), v);
2233+ widget->setFact (idx, fact);
2234+ };
2235+ void TestTplTextWidget::setUlongFact (uint idx, ulong v) {
2236+ Fact fact = Fact (FactMeta (" ulong" ), v);
2237+ widget->setFact (idx, fact);
2238+ };
2239+ void TestTplTextWidget::setDoubleFact (uint idx, double v) {
2240+ Fact fact = Fact (FactMeta (" double" ), v);
2241+ widget->setFact (idx, fact);
2242+ };
2243+ void TestTplTextWidget::setStringFact (uint idx, std::string v) {
2244+ Fact fact = Fact (FactMeta (" string" ), v);
2245+ widget->setFact (idx, fact);
2246+ };
2247+
2248+ void TestTplTextWidget::draw (void *cr) {
2249+ widget->draw ((cairo_t *) cr);
2250+ }
2251+
2252+ std::unique_ptr<std::string> TestTplTextWidget::render_tpl () {
2253+ return widget->render_tpl ();
2254+ }
2255+
2256+ #endif
0 commit comments