refactor: split static/ into css/ js/ html/; add tests/test_json.c (15/15 pass)
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
*.o
|
||||
iptv-dl
|
||||
tests/test_runner
|
||||
|
||||
@@ -34,20 +34,26 @@ $(TARGET): $(OBJS)
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
install: $(TARGET)
|
||||
install -d $(BINDIR) $(SHAREDIR) $(SYSCONFDIR)
|
||||
install -m 755 $(TARGET) $(BINDIR)/iptv-dl
|
||||
install -m 644 static/iptv.css $(SHAREDIR)/iptv.css
|
||||
install -m 644 static/iptv.js $(SHAREDIR)/iptv.js
|
||||
install -m 644 static/downloads.js $(SHAREDIR)/downloads.js
|
||||
install -m 644 static/series_show.js $(SHAREDIR)/series_show.js
|
||||
install -m 644 static/header.html $(SHAREDIR)/header.html
|
||||
install -m 644 static/footer.html $(SHAREDIR)/footer.html
|
||||
install -d $(BINDIR) $(SHAREDIR)/css $(SHAREDIR)/js $(SHAREDIR)/html $(SYSCONFDIR)
|
||||
install -m 755 $(TARGET) $(BINDIR)/iptv-dl
|
||||
install -m 644 static/css/iptv.css $(SHAREDIR)/css/iptv.css
|
||||
install -m 644 static/js/iptv.js $(SHAREDIR)/js/iptv.js
|
||||
install -m 644 static/js/downloads.js $(SHAREDIR)/js/downloads.js
|
||||
install -m 644 static/js/series_show.js $(SHAREDIR)/js/series_show.js
|
||||
install -m 644 static/html/header.html $(SHAREDIR)/html/header.html
|
||||
install -m 644 static/html/footer.html $(SHAREDIR)/html/footer.html
|
||||
@echo ""
|
||||
@echo "Installed to $(BINDIR)/iptv-dl"
|
||||
@echo "Create config at ~/.iptv-downloader/config.json or $(SYSCONFDIR)/config.json"
|
||||
@echo "Run: iptv-dl --dump-config (to see active defaults)"
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) $(TARGET)
|
||||
test: tests/test_runner
|
||||
./tests/test_runner
|
||||
|
||||
.PHONY: all install clean
|
||||
tests/test_runner: tests/test_json.c util/json.c util/buf.c
|
||||
$(CC) $(CFLAGS) $^ -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) $(TARGET) tests/test_runner
|
||||
|
||||
.PHONY: all install clean test
|
||||
|
||||
+6
-6
@@ -11,9 +11,9 @@ char *g_footer = NULL; int g_footer_len = 0;
|
||||
char *g_css = NULL; int g_css_len = 0;
|
||||
|
||||
StaticJS g_js[] = {
|
||||
{ "/iptv.js", "iptv.js", NULL, 0 },
|
||||
{ "/downloads.js", "downloads.js", NULL, 0 },
|
||||
{ "/series_show.js", "series_show.js", NULL, 0 },
|
||||
{ "/iptv.js", "js/iptv.js", NULL, 0 },
|
||||
{ "/downloads.js", "js/downloads.js", NULL, 0 },
|
||||
{ "/series_show.js", "js/series_show.js", NULL, 0 },
|
||||
{ NULL, NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
@@ -31,11 +31,11 @@ static int load_file(const char *path, char **out, int *out_len) {
|
||||
|
||||
int http_load_templates(void) {
|
||||
char path[512];
|
||||
snprintf(path, sizeof(path), "%s/header.html", g_cfg.template_dir);
|
||||
snprintf(path, sizeof(path), "%s/html/header.html", g_cfg.template_dir);
|
||||
if (!load_file(path, &g_header, &g_header_len)) return 0;
|
||||
snprintf(path, sizeof(path), "%s/footer.html", g_cfg.template_dir);
|
||||
snprintf(path, sizeof(path), "%s/html/footer.html", g_cfg.template_dir);
|
||||
if (!load_file(path, &g_footer, &g_footer_len)) return 0;
|
||||
snprintf(path, sizeof(path), "%s/iptv.css", g_cfg.template_dir);
|
||||
snprintf(path, sizeof(path), "%s/css/iptv.css", g_cfg.template_dir);
|
||||
if (!load_file(path, &g_css, &g_css_len)) return 0;
|
||||
for (int i = 0; g_js[i].url_path; i++) {
|
||||
snprintf(path, sizeof(path), "%s/%s", g_cfg.template_dir, g_js[i].fs_name);
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* tests/test_json.c — unit tests for util/json.c
|
||||
* Build: make test
|
||||
* Run: ./test_runner
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "json.h"
|
||||
|
||||
static int passed = 0, failed = 0;
|
||||
|
||||
#define CHECK(expr, desc) do { \
|
||||
if (expr) { printf(" PASS: %s\n", desc); passed++; } \
|
||||
else { printf(" FAIL: %s\n", desc); failed++; } \
|
||||
} while(0)
|
||||
|
||||
static void test_json_str(void) {
|
||||
printf("json_str:\n");
|
||||
const char *j = "{\"name\":\"test show\",\"id\":\"42\",\"flag\":true}";
|
||||
char *v;
|
||||
|
||||
v = json_str(j, "name"); CHECK(v && strcmp(v,"test show")==0, "string value"); free(v);
|
||||
v = json_str(j, "id"); CHECK(v && strcmp(v,"42")==0, "numeric string"); free(v);
|
||||
v = json_str(j, "flag"); CHECK(v && strcmp(v,"true")==0, "bare value"); free(v);
|
||||
v = json_str(j, "missing"); CHECK(v == NULL, "missing key"); free(v);
|
||||
}
|
||||
|
||||
static void test_json_array(void) {
|
||||
printf("json_array:\n");
|
||||
const char *j = "[{\"id\":\"1\"},{\"id\":\"2\"},{\"id\":\"3\"}]";
|
||||
int n; char **arr = json_array(j, &n);
|
||||
CHECK(n == 3, "count == 3");
|
||||
if (arr) {
|
||||
char *v = json_str(arr[0], "id"); CHECK(v && strcmp(v,"1")==0, "arr[0].id==1"); free(v);
|
||||
v = json_str(arr[2], "id"); CHECK(v && strcmp(v,"3")==0, "arr[2].id==3"); free(v);
|
||||
for (int i = 0; i < n; i++) free(arr[i]);
|
||||
free(arr);
|
||||
}
|
||||
/* empty array */
|
||||
arr = json_array("[]", &n); CHECK(n == 0, "empty array n==0"); free(arr);
|
||||
}
|
||||
|
||||
static void test_urldecode(void) {
|
||||
printf("urldecode:\n");
|
||||
char s1[] = "hello%20world"; urldecode(s1); CHECK(strcmp(s1,"hello world")==0, "%%20 → space");
|
||||
char s2[] = "a+b+c"; urldecode(s2); CHECK(strcmp(s2,"a b c")==0, "+ → space");
|
||||
char s3[] = "no%20change%21"; urldecode(s3); CHECK(strcmp(s3,"no change!")==0, "mixed");
|
||||
}
|
||||
|
||||
static void test_str_icontains(void) {
|
||||
printf("str_icontains:\n");
|
||||
CHECK(str_icontains("Walking Dead", "walking"), "case-insensitive match");
|
||||
CHECK(str_icontains("Walking Dead", "DEAD"), "uppercase needle");
|
||||
CHECK(!str_icontains("Walking Dead", "sopranos"),"no match");
|
||||
CHECK(str_icontains("anything", ""), "empty needle → true");
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
test_json_str();
|
||||
test_json_array();
|
||||
test_urldecode();
|
||||
test_str_icontains();
|
||||
printf("\n%d passed, %d failed\n", passed, failed);
|
||||
return failed ? 1 : 0;
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
Reference in New Issue
Block a user