==> tests/views.c <==1/* views.rs's records_round_trip_and_json, one for one. */
2#include "mesh/check.h"
3#include "mesh/views.h"
4
5#include <math.h>
6#include <stdlib.h>
7#include <string.h>
8
9int main(void) {
10 mesh_recs rs = MESH_RECS_INIT;
11 mesh_rec *r = mesh_recs_add(&rs, "fleet");
12 mesh_rec_kvu(r, "system", 0);
13 mesh_rec_kvu(r, "leader", 1);
14 mesh_rec_kvu(r, "term", 3);
15 mesh_rec_none(r, "suspect");
16 mesh_rec_kvu(r, "up", 0);
17 mesh_rec_kv(r, "job", "1.2");
18 r = mesh_recs_add(&rs, "member");
19 mesh_rec_kvu(r, "id", 2);
20 mesh_rec_kv(r, "host", "mac studio");
21 mesh_rec_kv(r, "share", "0.48");
22 mesh_rec_kv(r, "eq", "a=b");
23 mesh_rec_text(r, "busy: cpu \"psi\"\n0.31");
24 r = mesh_recs_add(&rs, "member");
25 mesh_rec_kvu(r, "id", 3);
26 mesh_rec_kv(r, "host", "");
27 mesh_rec_f(r, "share", true, 0.5, 2);
28 mesh_rec_f(r, "cpu", true, NAN, 2);
29 mesh_rec_kv(r, "zip", "007");
30
31 mesh_buf t = MESH_BUF_INIT;
32 mesh_views_text(&t, &rs);
33 CHECK_S(mesh_buf_str(&t), "fleet system=0 leader=1 term=3 suspect=- up=0 job=1.2\nmember id=2 host=mac_studio share=0.48 eq=a_b -- busy: cpu \"psi\" 0.31\nmember id=3 host=- share=0.50 cpu=- zip=007\n");
34
35 /* Parsed back: the same records. */
36 mesh_recs back = MESH_RECS_INIT;
37 mesh_views_parse(mesh_buf_str(&t), &back);
38 CHECK_U(back.len, 3);
39 mesh_buf t2 = MESH_BUF_INIT;
40 mesh_views_text(&t2, &back);
41 CHECK_S(mesh_buf_str(&t2), mesh_buf_str(&t));
42 CHECK_S(mesh_rec_get(&rs.items[1], "host"), "mac_studio");
43 CHECK(mesh_rec_get(&rs.items[2], "host") == NULL);
44 CHECK_S(back.items[1].text, "busy: cpu \"psi\" 0.31");
45
46 mesh_buf j = MESH_BUF_INIT;
47 mesh_views_json(&j, &rs);
48 CHECK_S(mesh_buf_str(&j), "{\"fleet\":[{\"system\":0,\"leader\":1,\"term\":3,\"suspect\":null,\"up\":\"0\",\"job\":\"1.2\"}],\"member\":[{\"id\":2,\"host\":\"mac_studio\",\"share\":0.48,\"eq\":\"a_b\",\"text\":\"busy: cpu \\\"psi\\\" 0.31\"},{\"id\":3,\"host\":null,\"share\":0.50,\"cpu\":null,\"zip\":\"007\"}]}\n");
49
50 struct { const char *v; bool n; } nums[] = {{"0", true}, {"-1.5e3", true}, {"1.", false}, {"1,2", false}, {"0x10", false},
51 {"-", false}, {"12ms", false}, {"00", false}};
52 for (size_t i = 0; i < sizeof nums / sizeof nums[0]; i++) CHECK(mesh_views_json_number(nums[i].v) == nums[i].n);
53
54 bool json = true;
55 char *err = NULL;
56 CHECK_I(mesh_views_format_of("", &json, &err), 0);
57 CHECK(!json);
58 CHECK_I(mesh_views_format_of("a=1&format=json", &json, &err), 0);
59 CHECK(json);
60 CHECK_I(mesh_views_format_of("format=xml", &json, &err), -1);
61 CHECK_S(err, "format=xml: json or text");
62 free(err);
63
64 /* A unicode space is one token separator too, and \r\n lines parse. */
65 mesh_recs u = MESH_RECS_INIT;
66 r = mesh_recs_add(&u, "x");
67 mesh_rec_kv(r, "h", "a\xc2\xa0" "b");
68 CHECK_S(u.items[0].kv[0].v, "a_b");
69 mesh_views_parse("k a=1\r\n\r\n \nk b=2 c\n", &back);
70 CHECK_U(back.len, 5);
71 CHECK_S(back.items[3].kv[0].v, "1");
72 CHECK_S(back.items[4].kv[1].k, "c");
73 CHECK_S(back.items[4].kv[1].v, "");
74
75 mesh_recs cp = MESH_RECS_INIT;
76 mesh_recs_extend(&cp, &rs);
77 mesh_buf t3 = MESH_BUF_INIT;
78 mesh_views_render(&t3, &cp, false);
79 CHECK_S(mesh_buf_str(&t3), mesh_buf_str(&t));
80 mesh_recs_free(&rs);
81 mesh_recs_free(&back);
82 mesh_recs_free(&u);
83 mesh_recs_free(&cp);
84 mesh_buf_free(&t);
85 mesh_buf_free(&t2);
86 mesh_buf_free(&t3);
87 mesh_buf_free(&j);
88 return mesh_check_done();
89}