三特性: 字体分层(gen_font.py --charset + meow_font_reload_tier + font.load_full + 尺寸标记) + 全屏机制/状态栏收合(meow_ui_sys/input) + 通知#6 TF转储(CSV+10MB+开机清板载+内存表)
This commit is contained in:
1 parent
0b4d1d3215
commit
a2673d5922
18 files changed
+819
-80
No files matched your search
@@ -0,0 +1,158 @@
|
||||
/* test_notif_tf.c — 宿主单测:通知#6 TF 转储(CSV 转义 / 10MB 滚动截断 / init 清板载+内存表)。
|
||||
*
|
||||
* 直接 #include "meow_notif.c"(同 TU 平移其 static 常量/函数),stub 掉 meow_settings_get_int
|
||||
* (配额读——返回负=键缺失即用默认,涵盖 CSV/截断/init 逻辑)。宿主 gcc 编译运行即可,不进固件。
|
||||
*
|
||||
* 运行:gcc -D_GNU_SOURCE -o test_notif_tf test_notif_tf.c && ./test_notif_tf
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* stub:meow_notif.c 的 read_quota() 读 notify.* 配额。<0 => 键缺失=> 用默认值 */
|
||||
int meow_settings_get_int(const char *key, int *out)
|
||||
{
|
||||
(void)key; (void)out;
|
||||
return -2; /* MEOW_ERR_NOENT */
|
||||
}
|
||||
|
||||
#include "meow_notif.c" /* 把全部实现(含 statics)收进本 TU */
|
||||
|
||||
static int g_fail = 0;
|
||||
#define CHECK(cond, msg) do { \
|
||||
if (!(cond)) { fprintf(stderr, "FAIL: %s (%s:%d)\n", msg, __FILE__, __LINE__); g_fail++; } \
|
||||
else fprintf(stderr, "ok: %s\n", msg); \
|
||||
} while (0)
|
||||
|
||||
static char *read_all(const char *path, long *out_len)
|
||||
{
|
||||
FILE *f = fopen(path, "rb");
|
||||
if (!f) return NULL;
|
||||
fseek(f, 0, SEEK_END);
|
||||
long n = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
char *s = malloc((size_t)n + 1);
|
||||
if (!s) { fclose(f); return NULL; }
|
||||
size_t got = fread(s, 1, (size_t)n, f);
|
||||
s[got] = 0;
|
||||
fclose(f);
|
||||
if (out_len) *out_len = n;
|
||||
return s;
|
||||
}
|
||||
|
||||
static void make_notif(meow_notif_t *n, uint32_t id, const char *sum, const char *body)
|
||||
{
|
||||
memset(n, 0, sizeof *n);
|
||||
n->id = id;
|
||||
n->created_ms = 1234567890123ULL;
|
||||
strcpy(n->app_id, "com.app");
|
||||
strcpy(n->category, "general");
|
||||
strcpy(n->summary, sum);
|
||||
strcpy(n->body, body);
|
||||
strcpy(n->target_activity, "act");
|
||||
n->ongoing = 1;
|
||||
}
|
||||
|
||||
/* --- 1) CSV 转义 + 去换行 --- */
|
||||
static void test_csv_escape(const char *path)
|
||||
{
|
||||
meow_notif_set_tf_path(path);
|
||||
meow_notif_set_tf_max(1024 * 1024); /* 放大上限避免此测触发截断 */
|
||||
|
||||
meow_notif_t n;
|
||||
/* summary: 逗号 + 双引号 + 换行;body: CRLF + tab */
|
||||
make_notif(&n, 42, "Hel\"lo, world\nline2", "Body\r\nwith\ttab");
|
||||
n.media = 1; /* 让 media 列=1 */
|
||||
CHECK(meow_notif_dump_tf(&n) == 0, "dump_tf returns 0");
|
||||
|
||||
char *s = read_all(path, NULL);
|
||||
CHECK(s != NULL, "file exists after dump");
|
||||
const char *expect =
|
||||
"1234567890123,42,\"com.app\",\"general\",\"\",\"Hel\"\"lo, world line2\","
|
||||
"\"Body with\ttab\",\"act\",1,1,0\n"; /* ongoing=1 media=1 dismissed=0 */
|
||||
CHECK(s && strcmp(s, expect) == 0, "CSV line matches expected (escape+newline-strip)");
|
||||
if (s) { fprintf(stderr, " got: %s", s); fprintf(stderr, " exp: %s", expect); }
|
||||
free(s);
|
||||
}
|
||||
|
||||
/* --- 2) 10MB 滚动截断(假文件:把上限压到很小模拟)--- */
|
||||
static void test_trim(const char *path)
|
||||
{
|
||||
meow_notif_set_tf_path(path);
|
||||
meow_notif_set_tf_max(256); /* 用 256B 模拟 10MB 上限 */
|
||||
|
||||
/* 先写 4 条不同标记,让文件超过 256B */
|
||||
meow_notif_t n;
|
||||
make_notif(&n, 1, "lineAAAA", "");
|
||||
meow_notif_dump_tf(&n);
|
||||
make_notif(&n, 2, "lineBBBB", "");
|
||||
meow_notif_dump_tf(&n);
|
||||
make_notif(&n, 3, "lineCCCC", "");
|
||||
meow_notif_dump_tf(&n);
|
||||
make_notif(&n, 4, "lineDDDD", "");
|
||||
meow_notif_dump_tf(&n);
|
||||
|
||||
long len = 0;
|
||||
char *s = read_all(path, &len);
|
||||
CHECK(s != NULL && len <= 256, "after roll, file size <= limit (10MB analog)");
|
||||
CHECK(s && strstr(s, "lineDDDD") != NULL, "newest row retained after roll");
|
||||
CHECK(s && strstr(s, "lineAAAA") == NULL, "oldest row rolled away");
|
||||
if (s) fprintf(stderr, " rolled content (%ldB):\n%s", len, s);
|
||||
|
||||
/* 追加一条仍 0 成功 */
|
||||
make_notif(&n, 5, "lineEEEE", "");
|
||||
CHECK(meow_notif_dump_tf(&n) == 0, "append after roll ok");
|
||||
free(s);
|
||||
}
|
||||
|
||||
/* --- 3) init 清板载 + 清内存表,且 post 正常 --- */
|
||||
static void test_init_clear(const char *path)
|
||||
{
|
||||
meow_notif_set_tf_path(path);
|
||||
meow_notif_set_tf_max(1024 * 1024);
|
||||
|
||||
/* 先塞点板载内容 */
|
||||
meow_notif_t n;
|
||||
make_notif(&n, 99, "junk", "");
|
||||
meow_notif_dump_tf(&n);
|
||||
|
||||
/* init:应清板载文件 + 清内存表 */
|
||||
CHECK(meow_notif_init() == NOTIF_OK, "meow_notif_init ok");
|
||||
long len = -1;
|
||||
char *s = read_all(path, &len);
|
||||
CHECK(s != NULL && len == 0, "board log cleared at init (dir kept)");
|
||||
CHECK(meow_notif_count(NULL) == 0, "memory table cleared at init");
|
||||
|
||||
/* init 后 post 一条,应活跃 + 可转储 */
|
||||
make_notif(&n, 0, "fresh", "");
|
||||
uint32_t id = 0;
|
||||
CHECK(meow_notif_post(&n, &id) == NOTIF_OK, "post after init ok");
|
||||
CHECK(id != 0 && meow_notif_count(NULL) == 1, "one active notif after post");
|
||||
free(s);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char tmp[] = "/tmp/meow_notif_tf_test_XXXXXX";
|
||||
char *dir = mkdtemp(tmp);
|
||||
if (!dir) { perror("mkdtemp"); return 2; }
|
||||
|
||||
char p1[512], p2[512], p3[512];
|
||||
snprintf(p1, sizeof p1, "%s/csv.log", dir);
|
||||
snprintf(p2, sizeof p2, "%s/trim.log", dir);
|
||||
snprintf(p3, sizeof p3, "%s/init.log", dir);
|
||||
|
||||
CHECK(p1[0] != 0, "tmpdir ready");
|
||||
test_csv_escape(p1);
|
||||
test_trim(p2);
|
||||
test_init_clear(p3);
|
||||
|
||||
/* 清理:删除日志文件 + 目录(保底) */
|
||||
unlink(p1); unlink(p2); unlink(p3); rmdir(dir);
|
||||
|
||||
fprintf(stderr, "\n%s (failures=%d)\n", g_fail ? "== TEST FAILED ==" : "== TEST PASSED ==", g_fail);
|
||||
return g_fail ? 1 : 0;
|
||||
}
|
||||
Reference in new issue
Block a user