summaryrefslogtreecommitdiff
path: root/src/tests/elementary/spec/efl_test_format.c
diff options
context:
space:
mode:
authorXavi Artigas <xavierartigas@yahoo.es>2019-07-02 14:40:06 +0200
committerXavi Artigas <xavierartigas@yahoo.es>2019-07-04 19:38:20 +0200
commite776f5f0d7b6292d32c29ccb4fffe3f20063d53d (patch)
tree0191eda9933ca930e90078fc9a35762b4b71538a /src/tests/elementary/spec/efl_test_format.c
parent87cfde51d3e143260a1b431f9c14d30536b549ce (diff)
Efl.Ui.Format revamp
This class helps widgets which contain a numerical value and must display it, like Progressbar (units label), Spin, Spin_Button, Slider (both units and popup labels, in legacy), Tags (when in shrunk mode) or Calendar (year_month label). Previously this was a mix of interface and mixin: widgets had to support setting a formatting func, and the mixin offered support for formatting strings, by setting an internal formatting func. On top of that, the spinner widget supported "special values", a list of values that should be shown as certain strings instead. This has now been simplified and unified: Widgets including this mixin can use the formatted_value_get() method which accepts an Eina_Value and returns a string. Thats's it. The mixin adds three properties to the widget (format_values, format_func and format_string) which users can use to tailor formatting. The widget does not need to know which method has been used, it just retrieves the resulting string. This removes a lot of duplicated widget code, and adds functionality which was missing before. For example, all widgets support passing a list of values now. Widgets must implement the apply_formatted_value() method so they are notified of changes in the format and they can redraw anything they need. Tests have been added to the Elementary Spec suite for all cases. Legacy widgets behavior has not been modified, although a few needed some code changes.
Diffstat (limited to 'src/tests/elementary/spec/efl_test_format.c')
-rw-r--r--src/tests/elementary/spec/efl_test_format.c174
1 files changed, 174 insertions, 0 deletions
diff --git a/src/tests/elementary/spec/efl_test_format.c b/src/tests/elementary/spec/efl_test_format.c
new file mode 100644
index 0000000000..cd2e698051
--- /dev/null
+++ b/src/tests/elementary/spec/efl_test_format.c
@@ -0,0 +1,174 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#define EFL_UI_FORMAT_PROTECTED /* To access internal methods */
6
7#include <Efl_Ui.h>
8#include "efl_ui_spec_suite.h"
9#include "suite_helpers.h"
10
11/* spec-meta-start
12 {"test-interface":"Efl.Ui.Format",
13 "test-widgets": ["Efl.Ui.Progressbar", "Efl.Ui.Calendar", "Efl.Ui.Tags", "Efl.Ui.Spin", "Efl.Ui.Spin_Button"]}
14 spec-meta-end */
15
16static const Efl_Ui_Format_Value values[] = {{15, "fifteen"}, {16, "sixteen"}, {17, "seventeen"}, {18, "eighteen"}};
17
18EFL_START_TEST(format_values)
19{
20 Eina_Strbuf *buf = eina_strbuf_new();
21 Eina_Value eina_val;
22
23 efl_ui_format_values_set(widget, EINA_C_ARRAY_ACCESSOR_NEW(values));
24 eina_val = eina_value_int_init(17);
25 efl_ui_format_formatted_value_get(widget, buf, eina_val);
26 ck_assert_str_eq(eina_strbuf_string_get(buf), "seventeen"); // Check that value works
27 eina_val = eina_value_float_init(16.f);
28 efl_ui_format_formatted_value_get(widget, buf, eina_val);
29 ck_assert_str_eq(eina_strbuf_string_get(buf), "sixteen"); // Check built-in conversion
30
31 eina_value_flush(&eina_val);
32 eina_strbuf_free(buf);
33}
34EFL_END_TEST
35
36static Eina_Bool
37_format_func(void *data, Eina_Strbuf *str, const Eina_Value value)
38{
39 int i = *(int *)data;
40 int v;
41 ck_assert_int_eq(i, 1234); // Check that data ptr is passed along correctly
42 if (eina_value_type_get(&value) != EINA_VALUE_TYPE_INT) return EINA_FALSE;
43 eina_value_get(&value, &v);
44 eina_strbuf_append_printf(str, "You said '%d'", v);
45
46 return EINA_TRUE;
47}
48
49static void
50_format_free_func(void *data)
51{
52 int i = *(int *)data;
53 ck_assert_int_eq(i, 1234); // Check that data ptr is passed along correctly
54 *(int *)data = 12345; // Change it to indicate that free func was called
55}
56
57EFL_START_TEST(format_func)
58{
59 int data = 1234;
60 Eina_Strbuf *buf = eina_strbuf_new();
61 Eina_Value eina_val;
62
63 efl_ui_format_func_set(widget, &data, _format_func, _format_free_func);
64 eina_val = eina_value_int_init(15);
65 efl_ui_format_formatted_value_get(widget, buf, eina_val);
66 ck_assert_str_eq(eina_strbuf_string_get(buf), "You said '15'"); // Check that format func works
67 efl_ui_format_func_set(widget, NULL, NULL, NULL);
68 ck_assert_int_eq(data, 12345); // Check that free func is called
69 eina_value_flush(&eina_val);
70
71 eina_strbuf_free(buf);
72}
73EFL_END_TEST
74
75EFL_START_TEST(format_string)
76{
77 Eina_Strbuf *buf = eina_strbuf_new();
78 Eina_Value eina_val;
79 struct tm t = { 0 };
80 const char *old_locale = setlocale(LC_TIME, NULL);
81
82#define CHECK(fmt_str, fmt_type, val, val_type, result) \
83 efl_ui_format_string_set(widget, fmt_str, fmt_type); \
84 eina_value_setup(&eina_val, val_type); \
85 eina_value_set(&eina_val, val); \
86 efl_ui_format_formatted_value_get(widget, buf, eina_val); \
87 ck_assert_str_eq(eina_strbuf_string_get(buf), result); \
88 eina_value_flush(&eina_val)
89
90 CHECK("%d", EFL_UI_FORMAT_STRING_TYPE_SIMPLE, 1234, EINA_VALUE_TYPE_INT, "1234");
91 CHECK("%d", EFL_UI_FORMAT_STRING_TYPE_SIMPLE, 1234.f, EINA_VALUE_TYPE_FLOAT, "1234"); // built-in conversion
92 CHECK("%d units", EFL_UI_FORMAT_STRING_TYPE_SIMPLE, 1234, EINA_VALUE_TYPE_INT, "1234 units"); // complex format
93
94 CHECK("%.0f", EFL_UI_FORMAT_STRING_TYPE_SIMPLE, 12.34f, EINA_VALUE_TYPE_FLOAT, "12");
95 CHECK("%.1f", EFL_UI_FORMAT_STRING_TYPE_SIMPLE, 12.34f, EINA_VALUE_TYPE_FLOAT, "12.3");
96 CHECK("%.2f", EFL_UI_FORMAT_STRING_TYPE_SIMPLE, 12.34f, EINA_VALUE_TYPE_FLOAT, "12.34");
97 CHECK("%.2f", EFL_UI_FORMAT_STRING_TYPE_SIMPLE, 1234, EINA_VALUE_TYPE_INT, "1234.00"); // built-in conversion
98 CHECK("%.0f%%", EFL_UI_FORMAT_STRING_TYPE_SIMPLE, 75.f, EINA_VALUE_TYPE_FLOAT, "75%"); // complex format
99
100 CHECK("%s", EFL_UI_FORMAT_STRING_TYPE_SIMPLE, "Hello!", EINA_VALUE_TYPE_STRING, "Hello!");
101 CHECK("%s", EFL_UI_FORMAT_STRING_TYPE_SIMPLE, 1234, EINA_VALUE_TYPE_INT, "1234"); // built-in conversion
102 CHECK("He said '%s'", EFL_UI_FORMAT_STRING_TYPE_SIMPLE, "Hello!", EINA_VALUE_TYPE_STRING, "He said 'Hello!'"); // complex format
103
104 CHECK("Static string", EFL_UI_FORMAT_STRING_TYPE_SIMPLE, 1234, EINA_VALUE_TYPE_INT, "Static string");
105
106 strptime("2019 7 3 11:49:3", "%Y %m %d %H:%M:%S", &t);
107 setlocale(LC_TIME, "C");
108 CHECK("%F", EFL_UI_FORMAT_STRING_TYPE_TIME, t, EINA_VALUE_TYPE_TM, "2019-07-03");
109 CHECK("%T", EFL_UI_FORMAT_STRING_TYPE_TIME, t, EINA_VALUE_TYPE_TM, "11:49:03");
110 CHECK("%A", EFL_UI_FORMAT_STRING_TYPE_TIME, t, EINA_VALUE_TYPE_TM, "Wednesday");
111 CHECK("<%B %Y>", EFL_UI_FORMAT_STRING_TYPE_TIME, t, EINA_VALUE_TYPE_TM, "<July 2019>");
112 setlocale(LC_TIME, old_locale);
113
114 eina_strbuf_free(buf);
115#undef CHECK
116}
117EFL_END_TEST
118
119static Eina_Bool
120_partial_format_func(void *data EINA_UNUSED, Eina_Strbuf *str, const Eina_Value value)
121{
122 int v;
123 if (eina_value_type_get(&value) != EINA_VALUE_TYPE_INT) return EINA_FALSE;
124 eina_value_get(&value, &v);
125 if (v < 10)
126 {
127 eina_strbuf_append_printf(str, "You said '%d'", v);
128 return EINA_TRUE;
129 }
130 return EINA_FALSE;
131}
132
133EFL_START_TEST(format_mixed)
134{
135 Eina_Strbuf *buf = eina_strbuf_new();
136 Eina_Value eina_val;
137
138 // Now we check combinations of different options
139 // Each one should be used in turn when the previous one fails: values, func, string, fallback
140 efl_ui_format_values_set(widget, EINA_C_ARRAY_ACCESSOR_NEW(values));
141 efl_ui_format_func_set(widget, NULL, _partial_format_func, NULL);
142 efl_ui_format_string_set(widget, "%d rabbits", EFL_UI_FORMAT_STRING_TYPE_SIMPLE);
143
144 eina_val = eina_value_int_init(1);
145 efl_ui_format_formatted_value_get(widget, buf, eina_val);
146 ck_assert_str_eq(eina_strbuf_string_get(buf), "You said '1'"); // Func
147 eina_value_set(&eina_val, 15);
148 efl_ui_format_formatted_value_get(widget, buf, eina_val);
149 ck_assert_str_eq(eina_strbuf_string_get(buf), "fifteen"); // Values
150 eina_value_set(&eina_val, 25);
151 efl_ui_format_formatted_value_get(widget, buf, eina_val);
152 ck_assert_str_eq(eina_strbuf_string_get(buf), "25 rabbits"); // Values
153
154 EXPECT_ERROR_START;
155 // This is an invalid format string (it has two placeholders) which should
156 // trigger the fallback mechanism
157 efl_ui_format_string_set(widget, "%d %d", EFL_UI_FORMAT_STRING_TYPE_SIMPLE);
158 EXPECT_ERROR_END;
159 efl_ui_format_formatted_value_get(widget, buf, eina_val);
160 ck_assert_str_eq(eina_strbuf_string_get(buf), "25"); // Fallback
161
162 eina_value_flush(&eina_val);
163 eina_strbuf_free(buf);
164}
165EFL_END_TEST
166
167void
168efl_ui_format_behavior_test(TCase *tc)
169{
170 tcase_add_test(tc, format_values);
171 tcase_add_test(tc, format_func);
172 tcase_add_test(tc, format_string);
173 tcase_add_test(tc, format_mixed);
174}