ddat interop with dat js cable interop with cabal js ddat's frontend = dat-thang cable fe = cable-thang dillo support based on cel's dillo-dat bootstrap node xplatform support Signed-off-by: divo <418@cryspace.space>
161 lines
6.1 KiB
C
161 lines
6.1 KiB
C
#include <SDL.h>
|
|
#ifdef main
|
|
#undef main
|
|
#endif
|
|
#define main dat_thang_program_main
|
|
#include "../src/ddat_gui.c"
|
|
#undef main
|
|
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#ifdef _WIN32
|
|
#include <direct.h>
|
|
#include <process.h>
|
|
#define test_getpid _getpid
|
|
#define test_mkdir(path) _mkdir(path)
|
|
#define test_setenv(name, value) _putenv_s((name), (value))
|
|
#else
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#define test_getpid getpid
|
|
#define test_mkdir(path) mkdir(path, 0700)
|
|
#define test_setenv(name, value) setenv((name), (value), 1)
|
|
#endif
|
|
|
|
int main(void)
|
|
{
|
|
static gui_state_t state;
|
|
dat_archive_t first, second;
|
|
char test_root[256], first_path[300], second_path[300];
|
|
char first_key[65], second_key[65];
|
|
int n, fixture_attempt;
|
|
setvbuf(stdout, NULL, _IONBF, 0);
|
|
memset(&state, 0, sizeof(state));
|
|
state.archive_open = 1;
|
|
state.version = 12;
|
|
state.selected_version = 12;
|
|
|
|
/* The displayed left/right halves of the version field are click targets. */
|
|
assert(click_archive_version_bar(&state, 210, 74, 84));
|
|
assert(state.selected_version == 11);
|
|
assert(click_archive_version_bar(&state, 226, 93, 84));
|
|
assert(state.selected_version == 12);
|
|
assert(click_archive_version_bar(&state, 226, 80, 84));
|
|
assert(state.selected_version == 12); /* clamp at latest */
|
|
assert(!click_archive_version_bar(&state, 209, 80, 84));
|
|
assert(!click_archive_version_bar(&state, 242, 80, 84));
|
|
assert(!click_archive_version_bar(&state, 210, 73, 84));
|
|
assert(!click_archive_version_bar(&state, 210, 94, 84));
|
|
state.archive_open = 0;
|
|
assert(!click_archive_version_bar(&state, 210, 80, 84));
|
|
puts("dat-thang version bar hitbox and bounds: PASS");
|
|
|
|
/* The visible version is the number of metadata entries after the feed
|
|
* header, while the Merkle tree counts every block including that header. */
|
|
assert(merkle_version_block_count(0, 0) == 1);
|
|
assert(merkle_version_block_count(3, 0) == 1);
|
|
assert(merkle_version_block_count(3, 2) == 3);
|
|
assert(merkle_version_block_count(3, 99) == 4);
|
|
{
|
|
uint64_t roots[4];
|
|
assert(sleep_tree_full_roots(3 * 2, roots, 4) == 2);
|
|
assert(roots[0] == 1 && roots[1] == 4);
|
|
}
|
|
puts("dat-thang Merkle view uses the selected SLEEP feed blocks: PASS");
|
|
|
|
/* Regression: browsing to another directory must not erase the loaded
|
|
* archive's address during the one-second archive refresh. */
|
|
for (fixture_attempt = 0; fixture_attempt < 1000; fixture_attempt++) {
|
|
n = snprintf(test_root, sizeof(test_root), "build/test-version-bar-%ld-%d",
|
|
(long)test_getpid(), fixture_attempt);
|
|
assert(n > 0 && (size_t)n < sizeof(test_root));
|
|
if (test_mkdir(test_root) == 0) break;
|
|
}
|
|
assert(fixture_attempt < 1000);
|
|
assert(test_setenv("USERPROFILE", test_root) == 0);
|
|
#ifdef _WIN32
|
|
assert(test_setenv("HOME", "") == 0);
|
|
#else
|
|
assert(test_setenv("HOME", test_root) == 0);
|
|
#endif
|
|
{
|
|
char path[1024];
|
|
strcpy(path, ".");
|
|
assert(parent_directory(path, sizeof(path)) == 1);
|
|
assert(strcmp(path, ".") != 0);
|
|
#ifdef _WIN32
|
|
char cwd[1024];
|
|
assert(_getcwd(cwd, sizeof(cwd)) != NULL);
|
|
snprintf(path, sizeof(path), "%c:\\", cwd[0]);
|
|
#else
|
|
strcpy(path, "/");
|
|
#endif
|
|
assert(parent_directory(path, sizeof(path)) == 0);
|
|
}
|
|
puts("dat-thang directory browser resolves relative parents and stops at root: PASS");
|
|
n = snprintf(first_path, sizeof(first_path), "%s/first", test_root);
|
|
assert(n > 0 && (size_t)n < sizeof(first_path));
|
|
n = snprintf(second_path, sizeof(second_path), "%s/second", test_root);
|
|
assert(n > 0 && (size_t)n < sizeof(second_path));
|
|
assert(test_mkdir(first_path) == 0 && test_mkdir(second_path) == 0);
|
|
assert(dat_archive_create(&first, first_path) == 0);
|
|
assert(dat_archive_create(&second, second_path) == 0);
|
|
memset(&state, 0, sizeof(state));
|
|
snprintf(state.shared_paths[0], sizeof(state.shared_paths[0]), "%s", first_path);
|
|
snprintf(state.shared_paths[1], sizeof(state.shared_paths[1]), "%s", second_path);
|
|
state.shared_path_count = 2;
|
|
assert(select_shared_archive(&state, 0) == 0);
|
|
assert(state.archive_open && !strcmp(state.archive_path, first_path));
|
|
assert(state.shared_path_count == 2);
|
|
assert(!strcmp(state.shared_paths[0], first_path));
|
|
assert(!strcmp(state.shared_paths[1], second_path));
|
|
puts("dat-thang right-click archive selection preserves the shared list: PASS");
|
|
assert(dat_key_to_hex(first.metadata_key, first_key) == 0);
|
|
assert(dat_key_to_hex(second.metadata_key, second_key) == 0);
|
|
assert(strcmp(first_key, second_key) != 0);
|
|
dat_archive_close(&first);
|
|
dat_archive_close(&second);
|
|
memset(&state, 0, sizeof(state));
|
|
state.identity_valid = 1;
|
|
memset(&state.identity, 0x5a, sizeof(state.identity));
|
|
snprintf(state.archive_path, sizeof(state.archive_path), "%s", first_path);
|
|
refresh_archive(&state);
|
|
assert(state.archive_open && !strcmp(state.archive_key, first_key));
|
|
assert(state.identity_valid);
|
|
for (size_t i = 0; i < sizeof(state.identity); i++)
|
|
assert(((const unsigned char *)&state.identity)[i] == 0x5a);
|
|
strcpy(state.site_name, "first.example.test");
|
|
state.site_name_editing = 1;
|
|
assert(save_site_name(&state) == 0);
|
|
state.site_name_editing = 0;
|
|
{
|
|
uint8_t resolved[DAT_KEY_BYTES];
|
|
assert(dat_dns_resolve("first.example.test", resolved, NULL) == 0);
|
|
assert(!memcmp(resolved, state.archive_key_bytes, sizeof(resolved)));
|
|
}
|
|
snprintf(state.archive_path, sizeof(state.archive_path), "%s", second_path);
|
|
refresh_archive_at(&state, state.archive_loaded_path);
|
|
assert(state.archive_open && !strcmp(state.archive_key, first_key));
|
|
assert(!strcmp(state.archive_path, second_path));
|
|
assert(!strcmp(state.site_name, "first.example.test"));
|
|
refresh_archive(&state);
|
|
assert(state.archive_open && !strcmp(state.archive_key, second_key));
|
|
assert(!state.site_name[0]);
|
|
assert(dat_dns_name_remove("first.example.test") == 0);
|
|
puts("dat-thang selected archive address survives browsing: PASS");
|
|
puts("dat-thang SITE alias persists to its archive key: PASS");
|
|
assert(test_setenv("CABLE_THANG_MANPAGE", "") == 0);
|
|
state.cable_thang_mode = 1;
|
|
load_manpage(&state);
|
|
{
|
|
int found = 0;
|
|
for (int line = 0; line < state.help_count; line++)
|
|
if (strstr(state.help_lines[line], "SDL2 Cable room chat client")) found = 1;
|
|
assert(found);
|
|
}
|
|
puts("cable-thang F1 loads the Cable manual: PASS");
|
|
return 0;
|
|
}
|