mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 10:48:20 +00:00
Fix Windows test compilation: mkdtemp, mkdir, setenv, pipe compat
- cbm_mkdtemp: _mktemp + _mkdir on Windows - cbm_setenv/cbm_unsetenv: _putenv_s on Windows - cbm_pipe: _pipe on Windows - Replace bare POSIX calls in 12 test files with compat wrappers - All test files now include compat.h
This commit is contained in:
1 parent
85fc74fc31
commit
fdb83f83f7
15 files changed
+242
-524
No files matched your search
Generated
-339
@@ -1,339 +0,0 @@
|
||||
{
|
||||
"name": "codebase-memory-mcp",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@anthropic-ai/claude-code": "^2.1.76"
|
||||
}
|
||||
},
|
||||
"node_modules/@anthropic-ai/claude-code": {
|
||||
"version": "2.1.76",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-code/-/claude-code-2.1.76.tgz",
|
||||
"integrity": "sha512-T6Uyl5Jw7fWiFaBqGZ1Faexm1nVc4P92KLLGbILoX4I/q3sRQrkDqrgwt0Jw45vMyfi794OrCP+BBSM267INZA==",
|
||||
"license": "SEE LICENSE IN README.md",
|
||||
"bin": {
|
||||
"claude": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-darwin-arm64": "^0.34.2",
|
||||
"@img/sharp-darwin-x64": "^0.34.2",
|
||||
"@img/sharp-linux-arm": "^0.34.2",
|
||||
"@img/sharp-linux-arm64": "^0.34.2",
|
||||
"@img/sharp-linux-x64": "^0.34.2",
|
||||
"@img/sharp-linuxmusl-arm64": "^0.34.2",
|
||||
"@img/sharp-linuxmusl-x64": "^0.34.2",
|
||||
"@img/sharp-win32-arm64": "^0.34.2",
|
||||
"@img/sharp-win32-x64": "^0.34.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-darwin-arm64": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz",
|
||||
"integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-darwin-arm64": "1.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-darwin-x64": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz",
|
||||
"integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-darwin-x64": "1.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-darwin-arm64": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz",
|
||||
"integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-darwin-x64": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz",
|
||||
"integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-arm": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz",
|
||||
"integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-arm64": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz",
|
||||
"integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-x64": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz",
|
||||
"integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linuxmusl-arm64": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz",
|
||||
"integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linuxmusl-x64": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz",
|
||||
"integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-arm": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz",
|
||||
"integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-arm": "1.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-arm64": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz",
|
||||
"integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-arm64": "1.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-x64": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz",
|
||||
"integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-x64": "1.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linuxmusl-arm64": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz",
|
||||
"integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linuxmusl-arm64": "1.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linuxmusl-x64": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz",
|
||||
"integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linuxmusl-x64": "1.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-win32-arm64": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz",
|
||||
"integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0 AND LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-win32-x64": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz",
|
||||
"integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0 AND LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@anthropic-ai/claude-code": "^2.1.76"
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,20 @@ char *cbm_strcasestr(const char *haystack, const char *needle) {
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ── mkdtemp (Windows lacks it) ───────────────────────────────── */
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
char *cbm_mkdtemp(char *tmpl) {
|
||||
/* _mktemp modifies template in place, then we mkdir */
|
||||
if (!_mktemp(tmpl))
|
||||
return NULL;
|
||||
if (_mkdir(tmpl) != 0)
|
||||
return NULL;
|
||||
return tmpl;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ── clock_gettime (Windows lacks it) ─────────────────────────── */
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
@@ -88,6 +88,36 @@ static inline int cbm_nanosleep(const struct timespec *req, struct timespec *rem
|
||||
#define cbm_nanosleep nanosleep
|
||||
#endif
|
||||
|
||||
/* ── mkdtemp (Windows lacks it) ──────────────────────────────── */
|
||||
#ifdef _WIN32
|
||||
char *cbm_mkdtemp(char *tmpl);
|
||||
#else
|
||||
#define cbm_mkdtemp mkdtemp
|
||||
#endif
|
||||
|
||||
/* ── setenv / unsetenv (Windows lacks them) ──────────────────── */
|
||||
#ifdef _WIN32
|
||||
static inline int cbm_setenv(const char *name, const char *value, int overwrite) {
|
||||
(void)overwrite;
|
||||
return _putenv_s(name, value);
|
||||
}
|
||||
static inline int cbm_unsetenv(const char *name) {
|
||||
return _putenv_s(name, "");
|
||||
}
|
||||
#else
|
||||
#define cbm_setenv setenv
|
||||
#define cbm_unsetenv unsetenv
|
||||
#endif
|
||||
|
||||
/* ── pipe (Windows uses _pipe) ───────────────────────────────── */
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#define cbm_pipe(fds) _pipe(fds, 4096, _O_BINARY)
|
||||
#else
|
||||
#define cbm_pipe(fds) pipe(fds)
|
||||
#endif
|
||||
|
||||
/* ── Signal handling ──────────────────────────────────────────── */
|
||||
/* Windows doesn't have sigaction; provide macro to select signal API. */
|
||||
#ifdef _WIN32
|
||||
|
||||
+86
-85
@@ -9,6 +9,7 @@
|
||||
*
|
||||
* Total: 47 Go tests → 47 C tests
|
||||
*/
|
||||
#include "../src/foundation/compat.h"
|
||||
#include "test_framework.h"
|
||||
#include <cli/cli.h>
|
||||
#include <foundation/yaml.h>
|
||||
@@ -49,11 +50,11 @@ static int test_mkdirp(const char *path) {
|
||||
for (char *p = tmp + 1; *p; p++) {
|
||||
if (*p == '/') {
|
||||
*p = '\0';
|
||||
mkdir(tmp, 0750);
|
||||
cbm_mkdir(tmp);
|
||||
*p = '/';
|
||||
}
|
||||
}
|
||||
return mkdir(tmp, 0750) == 0 || errno == EEXIST ? 0 : -1;
|
||||
return cbm_mkdir(tmp) == 0 || errno == EEXIST ? 0 : -1;
|
||||
}
|
||||
|
||||
/* Helper: recursive remove */
|
||||
@@ -174,35 +175,35 @@ TEST(cli_version_get_set) {
|
||||
|
||||
TEST(cli_detect_shell_rc_zsh) {
|
||||
char tmpdir[] = "/tmp/cli-rc-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
/* Save and override SHELL — must strdup because setenv may realloc env block */
|
||||
const char *raw = getenv("SHELL");
|
||||
char *old_shell = raw ? strdup(raw) : NULL;
|
||||
setenv("SHELL", "/bin/zsh", 1);
|
||||
cbm_setenv("SHELL", "/bin/zsh", 1);
|
||||
|
||||
const char *rc = cbm_detect_shell_rc(tmpdir);
|
||||
ASSERT_NOT_NULL(rc);
|
||||
ASSERT(strstr(rc, ".zshrc") != NULL);
|
||||
|
||||
if (old_shell) {
|
||||
setenv("SHELL", old_shell, 1);
|
||||
cbm_setenv("SHELL", old_shell, 1);
|
||||
free(old_shell);
|
||||
} else
|
||||
unsetenv("SHELL");
|
||||
cbm_unsetenv("SHELL");
|
||||
rmdir(tmpdir);
|
||||
PASS();
|
||||
}
|
||||
|
||||
TEST(cli_detect_shell_rc_bash) {
|
||||
char tmpdir[] = "/tmp/cli-rc-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
const char *raw = getenv("SHELL");
|
||||
char *old_shell = raw ? strdup(raw) : NULL;
|
||||
setenv("SHELL", "/bin/bash", 1);
|
||||
cbm_setenv("SHELL", "/bin/bash", 1);
|
||||
|
||||
/* No .bashrc → falls back to .bash_profile */
|
||||
const char *rc = cbm_detect_shell_rc(tmpdir);
|
||||
@@ -210,10 +211,10 @@ TEST(cli_detect_shell_rc_bash) {
|
||||
ASSERT(strstr(rc, ".bash_profile") != NULL);
|
||||
|
||||
if (old_shell) {
|
||||
setenv("SHELL", old_shell, 1);
|
||||
cbm_setenv("SHELL", old_shell, 1);
|
||||
free(old_shell);
|
||||
} else
|
||||
unsetenv("SHELL");
|
||||
cbm_unsetenv("SHELL");
|
||||
rmdir(tmpdir);
|
||||
PASS();
|
||||
}
|
||||
@@ -221,12 +222,12 @@ TEST(cli_detect_shell_rc_bash) {
|
||||
TEST(cli_detect_shell_rc_bash_with_bashrc) {
|
||||
/* Port of TestDetectShellRC_BashWithBashrc */
|
||||
char tmpdir[] = "/tmp/cli-rc-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
const char *raw = getenv("SHELL");
|
||||
char *old_shell = raw ? strdup(raw) : NULL;
|
||||
setenv("SHELL", "/bin/bash", 1);
|
||||
cbm_setenv("SHELL", "/bin/bash", 1);
|
||||
|
||||
/* Create .bashrc */
|
||||
char bashrc[512];
|
||||
@@ -238,52 +239,52 @@ TEST(cli_detect_shell_rc_bash_with_bashrc) {
|
||||
|
||||
unlink(bashrc);
|
||||
if (old_shell) {
|
||||
setenv("SHELL", old_shell, 1);
|
||||
cbm_setenv("SHELL", old_shell, 1);
|
||||
free(old_shell);
|
||||
} else
|
||||
unsetenv("SHELL");
|
||||
cbm_unsetenv("SHELL");
|
||||
rmdir(tmpdir);
|
||||
PASS();
|
||||
}
|
||||
|
||||
TEST(cli_detect_shell_rc_fish) {
|
||||
char tmpdir[] = "/tmp/cli-rc-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
const char *raw = getenv("SHELL");
|
||||
char *old_shell = raw ? strdup(raw) : NULL;
|
||||
setenv("SHELL", "/usr/bin/fish", 1);
|
||||
cbm_setenv("SHELL", "/usr/bin/fish", 1);
|
||||
|
||||
const char *rc = cbm_detect_shell_rc(tmpdir);
|
||||
ASSERT(strstr(rc, ".config/fish/config.fish") != NULL);
|
||||
|
||||
if (old_shell) {
|
||||
setenv("SHELL", old_shell, 1);
|
||||
cbm_setenv("SHELL", old_shell, 1);
|
||||
free(old_shell);
|
||||
} else
|
||||
unsetenv("SHELL");
|
||||
cbm_unsetenv("SHELL");
|
||||
rmdir(tmpdir);
|
||||
PASS();
|
||||
}
|
||||
|
||||
TEST(cli_detect_shell_rc_default) {
|
||||
char tmpdir[] = "/tmp/cli-rc-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
const char *raw = getenv("SHELL");
|
||||
char *old_shell = raw ? strdup(raw) : NULL;
|
||||
setenv("SHELL", "/bin/sh", 1);
|
||||
cbm_setenv("SHELL", "/bin/sh", 1);
|
||||
|
||||
const char *rc = cbm_detect_shell_rc(tmpdir);
|
||||
ASSERT(strstr(rc, ".profile") != NULL);
|
||||
|
||||
if (old_shell) {
|
||||
setenv("SHELL", old_shell, 1);
|
||||
cbm_setenv("SHELL", old_shell, 1);
|
||||
free(old_shell);
|
||||
} else
|
||||
unsetenv("SHELL");
|
||||
cbm_unsetenv("SHELL");
|
||||
rmdir(tmpdir);
|
||||
PASS();
|
||||
}
|
||||
@@ -295,18 +296,18 @@ TEST(cli_detect_shell_rc_default) {
|
||||
TEST(cli_find_cli_not_found) {
|
||||
/* Port of TestFindCLI_NotFound */
|
||||
char tmpdir[] = "/tmp/cli-find-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
const char *raw = getenv("PATH");
|
||||
char *old_path = raw ? strdup(raw) : NULL;
|
||||
setenv("PATH", tmpdir, 1);
|
||||
cbm_setenv("PATH", tmpdir, 1);
|
||||
|
||||
const char *result = cbm_find_cli("nonexistent-binary-xyz", tmpdir);
|
||||
ASSERT_STR_EQ(result, "");
|
||||
|
||||
if (old_path) {
|
||||
setenv("PATH", old_path, 1);
|
||||
cbm_setenv("PATH", old_path, 1);
|
||||
free(old_path);
|
||||
}
|
||||
rmdir(tmpdir);
|
||||
@@ -316,8 +317,8 @@ TEST(cli_find_cli_not_found) {
|
||||
TEST(cli_find_cli_on_path) {
|
||||
/* Port of TestFindCLI_FoundOnPATH */
|
||||
char tmpdir[] = "/tmp/cli-find-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char fakecli[512];
|
||||
snprintf(fakecli, sizeof(fakecli), "%s/fakecli", tmpdir);
|
||||
@@ -326,14 +327,14 @@ TEST(cli_find_cli_on_path) {
|
||||
|
||||
const char *raw = getenv("PATH");
|
||||
char *old_path = raw ? strdup(raw) : NULL;
|
||||
setenv("PATH", tmpdir, 1);
|
||||
cbm_setenv("PATH", tmpdir, 1);
|
||||
|
||||
const char *result = cbm_find_cli("fakecli", tmpdir);
|
||||
ASSERT(result[0] != '\0');
|
||||
ASSERT(strstr(result, "fakecli") != NULL);
|
||||
|
||||
if (old_path) {
|
||||
setenv("PATH", old_path, 1);
|
||||
cbm_setenv("PATH", old_path, 1);
|
||||
free(old_path);
|
||||
}
|
||||
unlink(fakecli);
|
||||
@@ -344,8 +345,8 @@ TEST(cli_find_cli_on_path) {
|
||||
TEST(cli_find_cli_fallback_paths) {
|
||||
/* Port of TestFindCLI_FallbackPaths */
|
||||
char tmpdir[] = "/tmp/cli-find-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char localbin[512];
|
||||
snprintf(localbin, sizeof(localbin), "%s/.local/bin", tmpdir);
|
||||
@@ -358,13 +359,13 @@ TEST(cli_find_cli_fallback_paths) {
|
||||
|
||||
const char *raw = getenv("PATH");
|
||||
char *old_path = raw ? strdup(raw) : NULL;
|
||||
setenv("PATH", "/nonexistent", 1);
|
||||
cbm_setenv("PATH", "/nonexistent", 1);
|
||||
|
||||
const char *result = cbm_find_cli("testcli", tmpdir);
|
||||
ASSERT_STR_EQ(result, fakecli);
|
||||
|
||||
if (old_path) {
|
||||
setenv("PATH", old_path, 1);
|
||||
cbm_setenv("PATH", old_path, 1);
|
||||
free(old_path);
|
||||
}
|
||||
test_rmdir_r(tmpdir);
|
||||
@@ -397,8 +398,8 @@ TEST(cli_dry_run_flags) {
|
||||
TEST(cli_skill_creation) {
|
||||
/* Port of TestInstallSkillCreation */
|
||||
char tmpdir[] = "/tmp/cli-skill-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char skills_dir[512];
|
||||
snprintf(skills_dir, sizeof(skills_dir), "%s/.claude/skills", tmpdir);
|
||||
@@ -427,8 +428,8 @@ TEST(cli_skill_creation) {
|
||||
TEST(cli_skill_idempotent) {
|
||||
/* Port of TestInstallIdempotent */
|
||||
char tmpdir[] = "/tmp/cli-skill-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char skills_dir[512];
|
||||
snprintf(skills_dir, sizeof(skills_dir), "%s/.claude/skills", tmpdir);
|
||||
@@ -456,8 +457,8 @@ TEST(cli_skill_idempotent) {
|
||||
TEST(cli_skill_force_overwrite) {
|
||||
/* Port of TestCLI_InstallForceOverwrites */
|
||||
char tmpdir[] = "/tmp/cli-skill-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char skills_dir[512];
|
||||
snprintf(skills_dir, sizeof(skills_dir), "%s/.claude/skills", tmpdir);
|
||||
@@ -475,8 +476,8 @@ TEST(cli_skill_force_overwrite) {
|
||||
TEST(cli_uninstall_removes_skills) {
|
||||
/* Port of TestUninstallRemovesSkills */
|
||||
char tmpdir[] = "/tmp/cli-skill-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char skills_dir[512];
|
||||
snprintf(skills_dir, sizeof(skills_dir), "%s/.claude/skills", tmpdir);
|
||||
@@ -501,8 +502,8 @@ TEST(cli_uninstall_removes_skills) {
|
||||
TEST(cli_remove_old_monolithic_skill) {
|
||||
/* Port of TestRemoveOldMonolithicSkill */
|
||||
char tmpdir[] = "/tmp/cli-skill-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char skills_dir[512];
|
||||
snprintf(skills_dir, sizeof(skills_dir), "%s/.claude/skills", tmpdir);
|
||||
@@ -580,8 +581,8 @@ TEST(cli_codex_instructions) {
|
||||
TEST(cli_editor_mcp_install) {
|
||||
/* Port of TestEditorMCPInstall */
|
||||
char tmpdir[] = "/tmp/cli-mcp-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/.cursor/mcp.json", tmpdir);
|
||||
@@ -602,8 +603,8 @@ TEST(cli_editor_mcp_install) {
|
||||
TEST(cli_editor_mcp_idempotent) {
|
||||
/* Port of TestEditorMCPInstallIdempotent */
|
||||
char tmpdir[] = "/tmp/cli-mcp-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/.cursor/mcp.json", tmpdir);
|
||||
@@ -632,8 +633,8 @@ TEST(cli_editor_mcp_idempotent) {
|
||||
TEST(cli_editor_mcp_preserves_others) {
|
||||
/* Port of TestEditorMCPPreservesOtherServers */
|
||||
char tmpdir[] = "/tmp/cli-mcp-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/.cursor/mcp.json", tmpdir);
|
||||
@@ -660,8 +661,8 @@ TEST(cli_editor_mcp_preserves_others) {
|
||||
TEST(cli_editor_mcp_uninstall) {
|
||||
/* Port of TestEditorMCPUninstall */
|
||||
char tmpdir[] = "/tmp/cli-mcp-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/.cursor/mcp.json", tmpdir);
|
||||
@@ -682,8 +683,8 @@ TEST(cli_editor_mcp_uninstall) {
|
||||
TEST(cli_gemini_mcp_install) {
|
||||
/* Port of TestGeminiMCPInstall */
|
||||
char tmpdir[] = "/tmp/cli-mcp-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/.gemini/settings.json", tmpdir);
|
||||
@@ -708,8 +709,8 @@ TEST(cli_gemini_mcp_install) {
|
||||
TEST(cli_vscode_mcp_install) {
|
||||
/* Port of TestVSCodeMCPInstall */
|
||||
char tmpdir[] = "/tmp/cli-mcp-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/Code/User/mcp.json", tmpdir);
|
||||
@@ -732,8 +733,8 @@ TEST(cli_vscode_mcp_install) {
|
||||
TEST(cli_vscode_mcp_uninstall) {
|
||||
/* Port of TestVSCodeMCPUninstall */
|
||||
char tmpdir[] = "/tmp/cli-mcp-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/Code/User/mcp.json", tmpdir);
|
||||
@@ -757,8 +758,8 @@ TEST(cli_vscode_mcp_uninstall) {
|
||||
TEST(cli_zed_mcp_install) {
|
||||
/* Port of TestZedMCPInstall */
|
||||
char tmpdir[] = "/tmp/cli-mcp-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/.config/zed/settings.json", tmpdir);
|
||||
@@ -781,8 +782,8 @@ TEST(cli_zed_mcp_install) {
|
||||
TEST(cli_zed_mcp_preserves_settings) {
|
||||
/* Port of TestZedMCPPreservesSettings */
|
||||
char tmpdir[] = "/tmp/cli-mcp-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/.config/zed/settings.json", tmpdir);
|
||||
@@ -811,8 +812,8 @@ TEST(cli_zed_mcp_preserves_settings) {
|
||||
TEST(cli_zed_mcp_uninstall) {
|
||||
/* Port of TestZedMCPUninstall */
|
||||
char tmpdir[] = "/tmp/cli-mcp-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/.config/zed/settings.json", tmpdir);
|
||||
@@ -836,8 +837,8 @@ TEST(cli_zed_mcp_uninstall) {
|
||||
TEST(cli_ensure_path_append) {
|
||||
/* Port of TestCLI_InstallPATHAppend */
|
||||
char tmpdir[] = "/tmp/cli-path-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char rcfile[512];
|
||||
snprintf(rcfile, sizeof(rcfile), "%s/.zshrc", tmpdir);
|
||||
@@ -855,8 +856,8 @@ TEST(cli_ensure_path_append) {
|
||||
|
||||
TEST(cli_ensure_path_already_present) {
|
||||
char tmpdir[] = "/tmp/cli-path-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char rcfile[512];
|
||||
snprintf(rcfile, sizeof(rcfile), "%s/.zshrc", tmpdir);
|
||||
@@ -871,8 +872,8 @@ TEST(cli_ensure_path_already_present) {
|
||||
|
||||
TEST(cli_ensure_path_dry_run) {
|
||||
char tmpdir[] = "/tmp/cli-path-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char rcfile[512];
|
||||
snprintf(rcfile, sizeof(rcfile), "%s/.zshrc", tmpdir);
|
||||
@@ -896,8 +897,8 @@ TEST(cli_ensure_path_dry_run) {
|
||||
TEST(cli_copy_file) {
|
||||
/* Port of TestCopyFile */
|
||||
char tmpdir[] = "/tmp/cli-copy-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char src[512], dst[512];
|
||||
snprintf(src, sizeof(src), "%s/source", tmpdir);
|
||||
@@ -918,8 +919,8 @@ TEST(cli_copy_file) {
|
||||
TEST(cli_copy_file_source_not_found) {
|
||||
/* Port of TestCopyFile_SourceNotFound */
|
||||
char tmpdir[] = "/tmp/cli-copy-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char src[512], dst[512];
|
||||
snprintf(src, sizeof(src), "%s/nonexistent", tmpdir);
|
||||
@@ -988,8 +989,8 @@ TEST(cli_extract_binary_from_targz_invalid_data) {
|
||||
TEST(cli_install_dry_run) {
|
||||
/* Port of TestCLI_InstallDryRun */
|
||||
char tmpdir[] = "/tmp/cli-dry-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char skills_dir[512];
|
||||
snprintf(skills_dir, sizeof(skills_dir), "%s/.claude/skills", tmpdir);
|
||||
@@ -1013,8 +1014,8 @@ TEST(cli_install_dry_run) {
|
||||
TEST(cli_uninstall_dry_run) {
|
||||
/* Port of TestCLI_UninstallDryRun */
|
||||
char tmpdir[] = "/tmp/cli-dry-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char skills_dir[512];
|
||||
snprintf(skills_dir, sizeof(skills_dir), "%s/.claude/skills", tmpdir);
|
||||
@@ -1043,8 +1044,8 @@ TEST(cli_uninstall_dry_run) {
|
||||
TEST(cli_install_and_uninstall) {
|
||||
/* Port of TestCLI_InstallAndUninstall */
|
||||
char tmpdir[] = "/tmp/cli-full-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char skills_dir[512];
|
||||
snprintf(skills_dir, sizeof(skills_dir), "%s/.claude/skills", tmpdir);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* Uses unit test approach: set up gbuf state directly, run strategies,
|
||||
* check CONFIGURES edges.
|
||||
*/
|
||||
#include "../src/foundation/compat.h"
|
||||
#include "test_framework.h"
|
||||
#include "pipeline/pipeline.h"
|
||||
#include "pipeline/pipeline_internal.h"
|
||||
@@ -240,12 +241,12 @@ TEST(configlink_file_ref_exact_path) {
|
||||
/* Create temp directory with files */
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_cfglink_XXXXXX");
|
||||
ASSERT_NOT_NULL(mkdtemp(tmpdir));
|
||||
ASSERT_NOT_NULL(cbm_mkdtemp(tmpdir));
|
||||
|
||||
/* Create config/database.toml */
|
||||
char cfg_dir[512];
|
||||
snprintf(cfg_dir, sizeof(cfg_dir), "%s/config", tmpdir);
|
||||
mkdir(cfg_dir, 0755);
|
||||
cbm_mkdir(cfg_dir);
|
||||
|
||||
char cfg_path[512];
|
||||
snprintf(cfg_path, sizeof(cfg_path), "%s/config/database.toml", tmpdir);
|
||||
@@ -303,7 +304,7 @@ TEST(configlink_file_ref_exact_path) {
|
||||
TEST(configlink_file_ref_basename_match) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_cfglink_XXXXXX");
|
||||
ASSERT_NOT_NULL(mkdtemp(tmpdir));
|
||||
ASSERT_NOT_NULL(cbm_mkdtemp(tmpdir));
|
||||
|
||||
/* Create settings.yaml */
|
||||
char cfg_path[512];
|
||||
@@ -353,7 +354,7 @@ TEST(configlink_file_ref_basename_match) {
|
||||
TEST(configlink_file_ref_no_false_positive) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_cfglink_XXXXXX");
|
||||
ASSERT_NOT_NULL(mkdtemp(tmpdir));
|
||||
ASSERT_NOT_NULL(cbm_mkdtemp(tmpdir));
|
||||
|
||||
/* Create data.csv */
|
||||
char csv_path[512];
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*
|
||||
* Total: 43 Go tests → 43 C tests
|
||||
*/
|
||||
#include "../src/foundation/compat.h"
|
||||
#include "test_framework.h"
|
||||
#include <pipeline/httplink.h>
|
||||
#include <foundation/yaml.h>
|
||||
@@ -549,8 +550,8 @@ TEST(httplink_load_config_default) {
|
||||
TEST(httplink_load_config_from_file) {
|
||||
/* Create temp dir with .cgrconfig */
|
||||
char tmpdir[] = "/tmp/httplink-cfg-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char cfgpath[512];
|
||||
snprintf(cfgpath, sizeof(cfgpath), "%s/.cgrconfig", tmpdir);
|
||||
@@ -589,8 +590,8 @@ TEST(httplink_load_config_from_file) {
|
||||
TEST(httplink_load_config_invalid_yaml) {
|
||||
/* Invalid YAML → fallback to defaults */
|
||||
char tmpdir[] = "/tmp/httplink-bad-XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char cfgpath[512];
|
||||
snprintf(cfgpath, sizeof(cfgpath), "%s/.cgrconfig", tmpdir);
|
||||
@@ -719,8 +720,8 @@ TEST(httplink_route_extraction_negative_cases) {
|
||||
TEST(httplink_read_source_lines) {
|
||||
/* Create temp dir with test file */
|
||||
char tmpdir[] = "/tmp/httplink-test-XXXXXX";
|
||||
if (!mkdtemp(tmpdir)) {
|
||||
printf(" SKIP: mkdtemp failed\n");
|
||||
if (!cbm_mkdtemp(tmpdir)) {
|
||||
printf(" SKIP: cbm_mkdtemp failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
* This exercises the complete flow: discover → extract → registry → graph
|
||||
* buffer → SQLite dump → query. No mocking — real files, real parsing.
|
||||
*/
|
||||
#include "../src/foundation/compat.h"
|
||||
#include "test_framework.h"
|
||||
#include <mcp/mcp.h>
|
||||
#include <store/store.h>
|
||||
@@ -29,7 +30,7 @@ static char *g_project = NULL;
|
||||
/* Create source files in temp directory */
|
||||
static int create_test_project(void) {
|
||||
snprintf(g_tmpdir, sizeof(g_tmpdir), "/tmp/cbm_integ_XXXXXX");
|
||||
if (!mkdtemp(g_tmpdir))
|
||||
if (!cbm_mkdtemp(g_tmpdir))
|
||||
return -1;
|
||||
|
||||
char path[512];
|
||||
@@ -112,7 +113,7 @@ static int integration_setup(void) {
|
||||
/* Ensure cache dir exists */
|
||||
char cache_dir[512];
|
||||
snprintf(cache_dir, sizeof(cache_dir), "%s/.cache/codebase-memory-mcp", home);
|
||||
mkdir(cache_dir, 0755);
|
||||
cbm_mkdir(cache_dir);
|
||||
|
||||
/* Remove stale db from previous test runs */
|
||||
unlink(g_dbpath);
|
||||
|
||||
+10
-2
@@ -6,9 +6,15 @@
|
||||
*/
|
||||
#include "test_framework.h"
|
||||
#include "../src/foundation/log.h"
|
||||
#include <unistd.h>
|
||||
#include "../src/foundation/compat.h"
|
||||
#include <stdbool.h>
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#else
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
/* Simple strstr wrapper used by log tests (avoids circular dep on str_util) */
|
||||
static inline bool cbm_str_contains_raw(const char *s, const char *sub) {
|
||||
@@ -22,9 +28,11 @@ static int pipe_fds[2];
|
||||
static void capture_start(void) {
|
||||
fflush(stderr);
|
||||
saved_stderr = dup(STDERR_FILENO);
|
||||
pipe(pipe_fds);
|
||||
cbm_pipe(pipe_fds);
|
||||
#ifndef _WIN32
|
||||
/* Set read end to non-blocking */
|
||||
fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK);
|
||||
#endif
|
||||
dup2(pipe_fds[1], STDERR_FILENO);
|
||||
close(pipe_fds[1]);
|
||||
}
|
||||
|
||||
+3
-2
@@ -3,6 +3,7 @@
|
||||
*
|
||||
* Covers: JSON-RPC parsing, MCP protocol, tool dispatch, tool handlers.
|
||||
*/
|
||||
#include "../src/foundation/compat.h"
|
||||
#include "test_framework.h"
|
||||
#include <mcp/mcp.h>
|
||||
#include <store/store.h>
|
||||
@@ -734,12 +735,12 @@ TEST(parse_file_uri_invalid) {
|
||||
static cbm_mcp_server_t *setup_snippet_server(char *tmp_dir, size_t tmp_sz) {
|
||||
/* Create temp dir */
|
||||
snprintf(tmp_dir, tmp_sz, "/tmp/cbm_snippet_test_XXXXXX");
|
||||
if (!mkdtemp(tmp_dir))
|
||||
if (!cbm_mkdtemp(tmp_dir))
|
||||
return NULL;
|
||||
|
||||
char proj_dir[512];
|
||||
snprintf(proj_dir, sizeof(proj_dir), "%s/project", tmp_dir);
|
||||
mkdir(proj_dir, 0750);
|
||||
cbm_mkdir(proj_dir);
|
||||
|
||||
/* Write sample source file */
|
||||
char src_path[512];
|
||||
|
||||
+2
-1
@@ -2,6 +2,7 @@
|
||||
* test_mem.c — Tests for unified memory management (mimalloc-backed),
|
||||
* arena integration, slab allocator, and parallel extraction.
|
||||
*/
|
||||
#include "../src/foundation/compat.h"
|
||||
#include "test_framework.h"
|
||||
#include "../src/foundation/mem.h"
|
||||
#include "../src/foundation/arena.h"
|
||||
@@ -328,7 +329,7 @@ static char g_mem_tmpdir[256];
|
||||
|
||||
static int setup_mem_test_repo(void) {
|
||||
snprintf(g_mem_tmpdir, sizeof(g_mem_tmpdir), "/tmp/cbm_mem_XXXXXX");
|
||||
if (!mkdtemp(g_mem_tmpdir)) {
|
||||
if (!cbm_mkdtemp(g_mem_tmpdir)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*
|
||||
* Suite: suite_parallel
|
||||
*/
|
||||
#include "../src/foundation/compat.h"
|
||||
#include "test_framework.h"
|
||||
#include "pipeline/pipeline.h"
|
||||
#include "pipeline/pipeline_internal.h"
|
||||
@@ -27,7 +28,7 @@ static char g_par_tmpdir[256];
|
||||
|
||||
static int setup_parallel_repo(void) {
|
||||
snprintf(g_par_tmpdir, sizeof(g_par_tmpdir), "/tmp/cbm_par_XXXXXX");
|
||||
if (!mkdtemp(g_par_tmpdir))
|
||||
if (!cbm_mkdtemp(g_par_tmpdir))
|
||||
return -1;
|
||||
|
||||
char path[512];
|
||||
@@ -43,7 +44,7 @@ static int setup_parallel_repo(void) {
|
||||
|
||||
/* pkg/ */
|
||||
snprintf(path, sizeof(path), "%s/pkg", g_par_tmpdir);
|
||||
mkdir(path, 0755);
|
||||
cbm_mkdir(path);
|
||||
|
||||
/* pkg/service.go */
|
||||
snprintf(path, sizeof(path), "%s/pkg/service.go", g_par_tmpdir);
|
||||
@@ -56,7 +57,7 @@ static int setup_parallel_repo(void) {
|
||||
|
||||
/* pkg/util/ */
|
||||
snprintf(path, sizeof(path), "%s/pkg/util", g_par_tmpdir);
|
||||
mkdir(path, 0755);
|
||||
cbm_mkdir(path);
|
||||
|
||||
/* pkg/util/helper.go */
|
||||
snprintf(path, sizeof(path), "%s/pkg/util/helper.go", g_par_tmpdir);
|
||||
|
||||
+23
-22
@@ -4,6 +4,7 @@
|
||||
* Tests pipeline lifecycle, structure pass, and end-to-end indexing
|
||||
* on a temporary directory with known file layout.
|
||||
*/
|
||||
#include "../src/foundation/compat.h"
|
||||
#include "test_framework.h"
|
||||
#include "pipeline/pipeline.h"
|
||||
#include "pipeline/pipeline_internal.h"
|
||||
@@ -32,7 +33,7 @@ static char g_tmpdir[256];
|
||||
*/
|
||||
static int setup_test_repo(void) {
|
||||
snprintf(g_tmpdir, sizeof(g_tmpdir), "/tmp/cbm_test_XXXXXX");
|
||||
if (!mkdtemp(g_tmpdir))
|
||||
if (!cbm_mkdtemp(g_tmpdir))
|
||||
return -1;
|
||||
|
||||
char path[512];
|
||||
@@ -51,7 +52,7 @@ static int setup_test_repo(void) {
|
||||
|
||||
/* pkg/ */
|
||||
snprintf(path, sizeof(path), "%s/pkg", g_tmpdir);
|
||||
mkdir(path, 0755);
|
||||
cbm_mkdir(path);
|
||||
|
||||
/* pkg/service.go — calls Help() from util */
|
||||
snprintf(path, sizeof(path), "%s/pkg/service.go", g_tmpdir);
|
||||
@@ -67,7 +68,7 @@ static int setup_test_repo(void) {
|
||||
|
||||
/* pkg/util/ */
|
||||
snprintf(path, sizeof(path), "%s/pkg/util", g_tmpdir);
|
||||
mkdir(path, 0755);
|
||||
cbm_mkdir(path);
|
||||
|
||||
/* pkg/util/helper.go */
|
||||
snprintf(path, sizeof(path), "%s/pkg/util/helper.go", g_tmpdir);
|
||||
@@ -819,7 +820,7 @@ static char g_usages_tmpdir[256];
|
||||
static int setup_usages_repo(const char *filename, const char *content, const char *extra_file,
|
||||
const char *extra_content) {
|
||||
snprintf(g_usages_tmpdir, sizeof(g_usages_tmpdir), "/tmp/cbm_usage_XXXXXX");
|
||||
if (!mkdtemp(g_usages_tmpdir))
|
||||
if (!cbm_mkdtemp(g_usages_tmpdir))
|
||||
return -1;
|
||||
|
||||
/* Check if filename has subdirectory */
|
||||
@@ -1106,7 +1107,7 @@ static char g_lang_tmpdir[256];
|
||||
|
||||
static int setup_lang_repo(const char **filenames, const char **contents, int count) {
|
||||
snprintf(g_lang_tmpdir, sizeof(g_lang_tmpdir), "/tmp/cbm_lang_XXXXXX");
|
||||
if (!mkdtemp(g_lang_tmpdir))
|
||||
if (!cbm_mkdtemp(g_lang_tmpdir))
|
||||
return -1;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
@@ -1544,7 +1545,7 @@ TEST(pipeline_csharp_modern) {
|
||||
TEST(pipeline_bom_stripping) {
|
||||
/* Port of TestBOMStripping — UTF-8 BOM prefix should be handled */
|
||||
snprintf(g_lang_tmpdir, sizeof(g_lang_tmpdir), "/tmp/cbm_bom_XXXXXX");
|
||||
if (!mkdtemp(g_lang_tmpdir))
|
||||
if (!cbm_mkdtemp(g_lang_tmpdir))
|
||||
SKIP("tmpdir");
|
||||
|
||||
char path[512];
|
||||
@@ -4152,7 +4153,7 @@ static void write_temp_file(const char *dir, const char *name, const char *conte
|
||||
memcpy(parent, path, plen);
|
||||
parent[plen] = '\0';
|
||||
/* mkdir -p (simple version, one level) */
|
||||
mkdir(parent, 0755);
|
||||
cbm_mkdir(parent);
|
||||
}
|
||||
FILE *f = fopen(path, "w");
|
||||
if (f) {
|
||||
@@ -4182,7 +4183,7 @@ static int has_binding_value(const cbm_env_binding_t *bindings, int count, const
|
||||
|
||||
TEST(envscan_dockerfile_env_urls) {
|
||||
char tmpdir[] = "/tmp/cbm_envscan_dock_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
|
||||
write_temp_file(tmpdir, "Dockerfile",
|
||||
@@ -4211,7 +4212,7 @@ TEST(envscan_dockerfile_env_urls) {
|
||||
|
||||
TEST(envscan_shell_env_urls) {
|
||||
char tmpdir[] = "/tmp/cbm_envscan_sh_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
|
||||
write_temp_file(tmpdir, "setup.sh",
|
||||
@@ -4238,7 +4239,7 @@ TEST(envscan_shell_env_urls) {
|
||||
|
||||
TEST(envscan_env_file_urls) {
|
||||
char tmpdir[] = "/tmp/cbm_envscan_env_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
|
||||
write_temp_file(tmpdir, ".env",
|
||||
@@ -4264,7 +4265,7 @@ TEST(envscan_env_file_urls) {
|
||||
|
||||
TEST(envscan_toml_urls) {
|
||||
char tmpdir[] = "/tmp/cbm_envscan_toml_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
|
||||
write_temp_file(tmpdir, "config.toml",
|
||||
@@ -4291,7 +4292,7 @@ TEST(envscan_toml_urls) {
|
||||
|
||||
TEST(envscan_yaml_urls) {
|
||||
char tmpdir[] = "/tmp/cbm_envscan_yaml_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
|
||||
write_temp_file(tmpdir, "config.yaml",
|
||||
@@ -4316,7 +4317,7 @@ TEST(envscan_yaml_urls) {
|
||||
|
||||
TEST(envscan_terraform_urls) {
|
||||
char tmpdir[] = "/tmp/cbm_envscan_tf_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
|
||||
write_temp_file(tmpdir, "variables.tf",
|
||||
@@ -4342,7 +4343,7 @@ TEST(envscan_terraform_urls) {
|
||||
|
||||
TEST(envscan_properties_urls) {
|
||||
char tmpdir[] = "/tmp/cbm_envscan_prop_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
|
||||
write_temp_file(tmpdir, "app.properties",
|
||||
@@ -4364,7 +4365,7 @@ TEST(envscan_properties_urls) {
|
||||
|
||||
TEST(envscan_secret_key_exclusion) {
|
||||
char tmpdir[] = "/tmp/cbm_envscan_skey_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
|
||||
write_temp_file(tmpdir, "Dockerfile",
|
||||
@@ -4392,7 +4393,7 @@ TEST(envscan_secret_key_exclusion) {
|
||||
|
||||
TEST(envscan_secret_value_exclusion) {
|
||||
char tmpdir[] = "/tmp/cbm_envscan_sval_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
|
||||
write_temp_file(
|
||||
@@ -4417,7 +4418,7 @@ TEST(envscan_secret_value_exclusion) {
|
||||
|
||||
TEST(envscan_secret_file_exclusion) {
|
||||
char tmpdir[] = "/tmp/cbm_envscan_sfile_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
|
||||
/* Secret file should be skipped */
|
||||
@@ -4450,23 +4451,23 @@ TEST(envscan_secret_file_exclusion) {
|
||||
|
||||
TEST(envscan_skips_ignored_dirs) {
|
||||
char tmpdir[] = "/tmp/cbm_envscan_ign_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
|
||||
/* File inside .git should be skipped */
|
||||
char gitdir[512];
|
||||
snprintf(gitdir, sizeof(gitdir), "%s/.git", tmpdir);
|
||||
mkdir(gitdir, 0755);
|
||||
cbm_mkdir(gitdir);
|
||||
write_temp_file(tmpdir, ".git/config.sh",
|
||||
"#!/bin/bash\nexport API_URL=\"https://api.example.com/v1\"\n");
|
||||
|
||||
/* File inside node_modules should be skipped */
|
||||
char nmdir[512];
|
||||
snprintf(nmdir, sizeof(nmdir), "%s/node_modules", tmpdir);
|
||||
mkdir(nmdir, 0755);
|
||||
cbm_mkdir(nmdir);
|
||||
char nmpkg[512];
|
||||
snprintf(nmpkg, sizeof(nmpkg), "%s/node_modules/pkg", tmpdir);
|
||||
mkdir(nmpkg, 0755);
|
||||
cbm_mkdir(nmpkg);
|
||||
write_temp_file(tmpdir, "node_modules/pkg/config.sh",
|
||||
"#!/bin/bash\nexport API_URL=\"https://api.example.com/v1\"\n");
|
||||
|
||||
@@ -4498,7 +4499,7 @@ TEST(envscan_skips_ignored_dirs) {
|
||||
|
||||
TEST(envscan_non_url_values_skipped) {
|
||||
char tmpdir[] = "/tmp/cbm_envscan_nurl_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
|
||||
write_temp_file(tmpdir, "Dockerfile",
|
||||
|
||||
+16
-15
@@ -3,6 +3,7 @@
|
||||
*
|
||||
* Covers: config persistence, embedded asset lookup, layout engine.
|
||||
*/
|
||||
#include "../src/foundation/compat.h"
|
||||
#include "test_framework.h"
|
||||
#include "ui/config.h"
|
||||
#include "ui/embedded_assets.h"
|
||||
@@ -24,11 +25,11 @@ TEST(config_load_defaults) {
|
||||
|
||||
/* Use a temp HOME to avoid touching real config */
|
||||
char tmpdir[] = "/tmp/cbm_test_config_XXXXXX";
|
||||
char *td = mkdtemp(tmpdir);
|
||||
char *td = cbm_mkdtemp(tmpdir);
|
||||
ASSERT_NOT_NULL(td);
|
||||
|
||||
char *old_home = getenv("HOME") ? strdup(getenv("HOME")) : NULL;
|
||||
setenv("HOME", td, 1);
|
||||
cbm_setenv("HOME", td, 1);
|
||||
|
||||
cbm_ui_config_load(&cfg);
|
||||
|
||||
@@ -37,7 +38,7 @@ TEST(config_load_defaults) {
|
||||
|
||||
/* Restore HOME */
|
||||
if (old_home) {
|
||||
setenv("HOME", old_home, 1);
|
||||
cbm_setenv("HOME", old_home, 1);
|
||||
free(old_home);
|
||||
}
|
||||
|
||||
@@ -46,11 +47,11 @@ TEST(config_load_defaults) {
|
||||
|
||||
TEST(config_save_and_reload) {
|
||||
char tmpdir[] = "/tmp/cbm_test_config_XXXXXX";
|
||||
char *td = mkdtemp(tmpdir);
|
||||
char *td = cbm_mkdtemp(tmpdir);
|
||||
ASSERT_NOT_NULL(td);
|
||||
|
||||
char *old_home = getenv("HOME") ? strdup(getenv("HOME")) : NULL;
|
||||
setenv("HOME", td, 1);
|
||||
cbm_setenv("HOME", td, 1);
|
||||
|
||||
/* Save */
|
||||
cbm_ui_config_t cfg = {.ui_enabled = true, .ui_port = 8080};
|
||||
@@ -64,7 +65,7 @@ TEST(config_save_and_reload) {
|
||||
ASSERT_EQ(loaded.ui_port, 8080);
|
||||
|
||||
if (old_home) {
|
||||
setenv("HOME", old_home, 1);
|
||||
cbm_setenv("HOME", old_home, 1);
|
||||
free(old_home);
|
||||
}
|
||||
|
||||
@@ -73,11 +74,11 @@ TEST(config_save_and_reload) {
|
||||
|
||||
TEST(config_overwrite) {
|
||||
char tmpdir[] = "/tmp/cbm_test_config_XXXXXX";
|
||||
char *td = mkdtemp(tmpdir);
|
||||
char *td = cbm_mkdtemp(tmpdir);
|
||||
ASSERT_NOT_NULL(td);
|
||||
|
||||
char *old_home = getenv("HOME") ? strdup(getenv("HOME")) : NULL;
|
||||
setenv("HOME", td, 1);
|
||||
cbm_setenv("HOME", td, 1);
|
||||
|
||||
/* Save with ui_enabled=true */
|
||||
cbm_ui_config_t cfg1 = {.ui_enabled = true, .ui_port = 9749};
|
||||
@@ -93,7 +94,7 @@ TEST(config_overwrite) {
|
||||
ASSERT_FALSE(loaded.ui_enabled);
|
||||
|
||||
if (old_home) {
|
||||
setenv("HOME", old_home, 1);
|
||||
cbm_setenv("HOME", old_home, 1);
|
||||
free(old_home);
|
||||
}
|
||||
|
||||
@@ -102,11 +103,11 @@ TEST(config_overwrite) {
|
||||
|
||||
TEST(config_corrupt_file) {
|
||||
char tmpdir[] = "/tmp/cbm_test_config_XXXXXX";
|
||||
char *td = mkdtemp(tmpdir);
|
||||
char *td = cbm_mkdtemp(tmpdir);
|
||||
ASSERT_NOT_NULL(td);
|
||||
|
||||
char *old_home = getenv("HOME") ? strdup(getenv("HOME")) : NULL;
|
||||
setenv("HOME", td, 1);
|
||||
cbm_setenv("HOME", td, 1);
|
||||
|
||||
/* Write garbage to config path */
|
||||
char path[1024];
|
||||
@@ -131,7 +132,7 @@ TEST(config_corrupt_file) {
|
||||
ASSERT_EQ(cfg.ui_port, 9749);
|
||||
|
||||
if (old_home) {
|
||||
setenv("HOME", old_home, 1);
|
||||
cbm_setenv("HOME", old_home, 1);
|
||||
free(old_home);
|
||||
}
|
||||
|
||||
@@ -140,11 +141,11 @@ TEST(config_corrupt_file) {
|
||||
|
||||
TEST(config_missing_fields) {
|
||||
char tmpdir[] = "/tmp/cbm_test_config_XXXXXX";
|
||||
char *td = mkdtemp(tmpdir);
|
||||
char *td = cbm_mkdtemp(tmpdir);
|
||||
ASSERT_NOT_NULL(td);
|
||||
|
||||
char *old_home = getenv("HOME") ? strdup(getenv("HOME")) : NULL;
|
||||
setenv("HOME", td, 1);
|
||||
cbm_setenv("HOME", td, 1);
|
||||
|
||||
/* Write JSON with only ui_port */
|
||||
char path[1024];
|
||||
@@ -167,7 +168,7 @@ TEST(config_missing_fields) {
|
||||
ASSERT_EQ(cfg.ui_port, 5555); /* present field loaded */
|
||||
|
||||
if (old_home) {
|
||||
setenv("HOME", old_home, 1);
|
||||
cbm_setenv("HOME", old_home, 1);
|
||||
free(old_home);
|
||||
}
|
||||
|
||||
|
||||
+39
-38
@@ -4,6 +4,7 @@
|
||||
* Covers: adaptive interval, watch/unwatch lifecycle, git change detection,
|
||||
* poll_once behavior.
|
||||
*/
|
||||
#include "../src/foundation/compat.h"
|
||||
#include "test_framework.h"
|
||||
#include <watcher/watcher.h>
|
||||
#include <store/store.h>
|
||||
@@ -229,8 +230,8 @@ TEST(watcher_stop_flag) {
|
||||
TEST(watcher_detects_git_commit) {
|
||||
/* Create a temporary git repo */
|
||||
char tmpdir[] = "/tmp/cbm_watcher_test_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -282,8 +283,8 @@ TEST(watcher_detects_git_commit) {
|
||||
TEST(watcher_detects_dirty_worktree) {
|
||||
/* Create a temporary git repo */
|
||||
char tmpdir[] = "/tmp/cbm_watcher_dirty_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -326,8 +327,8 @@ TEST(watcher_detects_dirty_worktree) {
|
||||
TEST(watcher_detects_new_file) {
|
||||
/* Create a temporary git repo */
|
||||
char tmpdir[] = "/tmp/cbm_watcher_newf_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -371,8 +372,8 @@ TEST(watcher_detects_new_file) {
|
||||
TEST(watcher_no_change_no_reindex) {
|
||||
/* Create a temporary git repo */
|
||||
char tmpdir[] = "/tmp/cbm_watcher_nochg_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -415,8 +416,8 @@ TEST(watcher_multiple_projects) {
|
||||
/* Create two temporary git repos */
|
||||
char tmpdirA[] = "/tmp/cbm_watcher_mA_XXXXXX";
|
||||
char tmpdirB[] = "/tmp/cbm_watcher_mB_XXXXXX";
|
||||
if (!mkdtemp(tmpdirA) || !mkdtemp(tmpdirB))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdirA) || !cbm_mkdtemp(tmpdirB))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -475,8 +476,8 @@ TEST(watcher_non_git_skips) {
|
||||
/* Non-git dir → baseline sets is_git=false → poll never reindexes.
|
||||
* Port of TestProbeStrategyNonGit behavior. */
|
||||
char tmpdir[] = "/tmp/cbm_watcher_nongit_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
/* Create a file so it's not empty */
|
||||
char cmd[512];
|
||||
@@ -524,8 +525,8 @@ TEST(watcher_interval_blocks_repoll) {
|
||||
* immediate re-polling. Without touch(), the next poll is a no-op.
|
||||
* Port of TestWatcherGitNoChanges' interval behavior. */
|
||||
char tmpdir[] = "/tmp/cbm_watcher_intv_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -598,8 +599,8 @@ TEST(watcher_git_removed_no_crash) {
|
||||
* Port of TestStrategyDowngradeGitToDirMtime behavior (C version
|
||||
* doesn't downgrade — just git commands fail silently). */
|
||||
char tmpdir[] = "/tmp/cbm_watcher_rmgit_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -643,8 +644,8 @@ TEST(watcher_continued_dirty) {
|
||||
/* If working tree stays dirty, each poll should re-trigger reindex.
|
||||
* Port of repeated git sentinel detection behavior. */
|
||||
char tmpdir[] = "/tmp/cbm_watcher_cont_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -711,8 +712,8 @@ TEST(watcher_baseline_dirty_repo) {
|
||||
/* Baseline on a repo that already has uncommitted changes.
|
||||
* Port of TestGitSentinelDetectsEdit (dirty from the start). */
|
||||
char tmpdir[] = "/tmp/cbm_watcher_bld_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -755,8 +756,8 @@ TEST(watcher_unwatch_prunes_state) {
|
||||
/* Watch, baseline, unwatch → project state removed.
|
||||
* Port of TestPollAllPrunesUnwatched + TestWatcherPrunesDeletedProjects. */
|
||||
char tmpdir[] = "/tmp/cbm_watcher_prune_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -801,8 +802,8 @@ TEST(watcher_watch_after_unwatch) {
|
||||
/* Re-watching after unwatch should start fresh (new baseline).
|
||||
* Tests lifecycle correctness. */
|
||||
char tmpdir[] = "/tmp/cbm_watcher_rewatch_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -862,8 +863,8 @@ TEST(watcher_detects_file_delete) {
|
||||
/* Port of TestFSNotifyDetectsFileDelete:
|
||||
* Delete a tracked file → git status shows change → reindex triggered. */
|
||||
char tmpdir[] = "/tmp/cbm_watcher_del_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -907,8 +908,8 @@ TEST(watcher_detects_subdir_file) {
|
||||
/* Port of TestFSNotifyWatchesNewSubdir:
|
||||
* Create new subdir + file in it → git detects untracked → reindex. */
|
||||
char tmpdir[] = "/tmp/cbm_watcher_sub_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -978,8 +979,8 @@ TEST(watcher_full_flow_new_file) {
|
||||
* This is a more thorough version of watcher_detects_new_file
|
||||
* that mirrors the Go test's structure exactly. */
|
||||
char tmpdir[] = "/tmp/cbm_watcher_ffnf_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -1028,8 +1029,8 @@ TEST(watcher_fallback_still_detects) {
|
||||
* still detects changes. In C, we test that after removing .git
|
||||
* and re-creating it, changes are still detected on re-watch. */
|
||||
char tmpdir[] = "/tmp/cbm_watcher_fb_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -1087,8 +1088,8 @@ TEST(watcher_poll_only_watched_projects) {
|
||||
* gets polled and can trigger reindex. */
|
||||
char tmpdirA[] = "/tmp/cbm_watcher_owA_XXXXXX";
|
||||
char tmpdirB[] = "/tmp/cbm_watcher_owB_XXXXXX";
|
||||
if (!mkdtemp(tmpdirA) || !mkdtemp(tmpdirB))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdirA) || !cbm_mkdtemp(tmpdirB))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
/* Init both repos */
|
||||
@@ -1145,8 +1146,8 @@ TEST(watcher_touch_resets_immediate) {
|
||||
* Verify that touch() resets the adaptive backoff so the next
|
||||
* poll actually checks for changes immediately. */
|
||||
char tmpdir[] = "/tmp/cbm_watcher_tch_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -1195,8 +1196,8 @@ TEST(watcher_modify_tracked_file) {
|
||||
* Similar to watcher_detects_dirty_worktree but modifies specific
|
||||
* tracked file content rather than appending. */
|
||||
char tmpdir[] = "/tmp/cbm_watcher_mod_XXXXXX";
|
||||
if (!mkdtemp(tmpdir))
|
||||
SKIP("mkdtemp failed");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
|
||||
Reference in new issue
Block a user