refactor: Fixed the rest of the (tested) leaks.

This commit is contained in:
2026-06-12 13:42:37 -04:00
parent 365e9149b1
commit 7d16dae4f4
9 changed files with 41 additions and 64 deletions

View File

@@ -17,10 +17,10 @@ test_usage_text_contains_all_commands :: proc(t: ^testing.T) {
testing.expect( testing.expect(
t, t,
strings.contains(text, c.name), strings.contains(text, c.name),
fmt.aprintf("usage missing command %q", c.name), fmt.tprintf("usage missing command %q", c.name),
) )
for a in c.aliases { for a in c.aliases {
testing.expect(t, strings.contains(text, a), fmt.aprintf("usage missing alias %q", a)) testing.expect(t, strings.contains(text, a), fmt.tprintf("usage missing alias %q", a))
} }
} }
} }

View File

@@ -9,12 +9,12 @@ test_find_unbacked_finds_missing :: proc(t: ^testing.T) {
db := []EnvFile{{Path = "/a/.env"}, {Path = "/b/.env"}} db := []EnvFile{{Path = "/a/.env"}, {Path = "/b/.env"}}
result := find_unbacked(local, db[:]) result := find_unbacked(local, db[:])
testing.expect(t, len(result) == 1, fmt.aprintf("expected 1 unbacked, got %d", len(result))) testing.expect(t, len(result) == 1, fmt.tprintf("expected 1 unbacked, got %d", len(result)))
if len(result) > 0 { if len(result) > 0 {
testing.expect( testing.expect(
t, t,
result[0] == "/c/.env", result[0] == "/c/.env",
fmt.aprintf("expected /c/.env, got %s", result[0]), fmt.tprintf("expected /c/.env, got %s", result[0]),
) )
} }
} }
@@ -25,7 +25,7 @@ test_find_unbacked_all_backed :: proc(t: ^testing.T) {
db := []EnvFile{{Path = "/a/.env"}, {Path = "/b/.env"}} db := []EnvFile{{Path = "/a/.env"}, {Path = "/b/.env"}}
result := find_unbacked(local, db[:]) result := find_unbacked(local, db[:])
testing.expect(t, len(result) == 0, fmt.aprintf("expected 0 unbacked, got %d", len(result))) testing.expect(t, len(result) == 0, fmt.tprintf("expected 0 unbacked, got %d", len(result)))
} }
@(test) @(test)
@@ -34,7 +34,7 @@ test_find_unbacked_no_local :: proc(t: ^testing.T) {
db := []EnvFile{{Path = "/a/.env"}} db := []EnvFile{{Path = "/a/.env"}}
result := find_unbacked(local, db[:]) result := find_unbacked(local, db[:])
testing.expect(t, len(result) == 0, fmt.aprintf("expected 0 unbacked, got %d", len(result))) testing.expect(t, len(result) == 0, fmt.tprintf("expected 0 unbacked, got %d", len(result)))
} }
@(test) @(test)
@@ -43,6 +43,6 @@ test_find_unbacked_none_backed :: proc(t: ^testing.T) {
db: []EnvFile db: []EnvFile
result := find_unbacked(local, db[:]) result := find_unbacked(local, db[:])
testing.expect(t, len(result) == 2, fmt.aprintf("expected 2 unbacked, got %d", len(result))) testing.expect(t, len(result) == 2, fmt.tprintf("expected 2 unbacked, got %d", len(result)))
} }

View File

@@ -5,22 +5,14 @@ import "core:testing"
@(test) @(test)
test_filepath_base_equals_rel :: proc(t: ^testing.T) { test_filepath_base_equals_rel :: proc(t: ^testing.T) {
cases := []string{ cases := []string{"/home/user/.env", "/home/user/project/.envrc", "/tmp/foo", "/a/b/c/d.txt"}
"/home/user/.env",
"/home/user/project/.envrc",
"/tmp/foo",
"/a/b/c/d.txt",
}
for path in cases { for path in cases {
dir := filepath.dir(path) dir := filepath.dir(path)
rel, rel_err := filepath.rel(dir, path) rel, rel_err := filepath.rel(dir, path, context.temp_allocator)
testing.expect(t, rel_err == nil, "filepath.rel returned an error") testing.expect(t, rel_err == nil, "filepath.rel returned an error")
base := filepath.base(path) base := filepath.base(path)
testing.expect( testing.expect(t, rel == base, "filepath.rel(dir, path) should equal filepath.base(path)")
t,
rel == base,
"filepath.rel(dir, path) should equal filepath.base(path)",
)
} }
} }

View File

@@ -577,7 +577,7 @@ env_file_sync :: proc(f: ^EnvFile, dir: SyncDirection, d: ^Db) -> (SyncResult, s
if file_stat_err != nil { if file_stat_err != nil {
write_err := os.write_entire_file(f.Path, f.contents) write_err := os.write_entire_file(f.Path, f.contents)
if write_err != nil { if write_err != nil {
msg, _ := strings.concatenate({"failed to write file: ", fmt.aprintf("%v", write_err)}) msg, _ := strings.concatenate({"failed to write file: ", fmt.tprintf("%v", write_err)})
return .Error, msg return .Error, msg
} }
@@ -587,7 +587,7 @@ env_file_sync :: proc(f: ^EnvFile, dir: SyncDirection, d: ^Db) -> (SyncResult, s
data, read_err := os.read_entire_file_from_path(f.Path, context.allocator) data, read_err := os.read_entire_file_from_path(f.Path, context.allocator)
if read_err != nil { if read_err != nil {
msg, _ := strings.concatenate({"failed to read file for SHA comparison: ", fmt.aprintf("%v", read_err)}) msg, _ := strings.concatenate({"failed to read file for SHA comparison: ", fmt.tprintf("%v", read_err)})
return .Error, msg return .Error, msg
} }
@@ -603,7 +603,7 @@ env_file_sync :: proc(f: ^EnvFile, dir: SyncDirection, d: ^Db) -> (SyncResult, s
case .TrustDatabase: case .TrustDatabase:
write_err := os.write_entire_file(f.Path, f.contents) write_err := os.write_entire_file(f.Path, f.contents)
if write_err != nil { if write_err != nil {
msg, _ := strings.concatenate({"failed to write file: ", fmt.aprintf("%v", write_err)}) msg, _ := strings.concatenate({"failed to write file: ", fmt.tprintf("%v", write_err)})
return .Error, msg return .Error, msg
} }
s := i32(result) | i32(SyncResult.Restored) s := i32(result) | i32(SyncResult.Restored)

View File

@@ -1,19 +0,0 @@
package main
import "core:path/filepath"
import "core:strings"
import "core:testing"
@(test)
test_dir_slice_owns_parent :: proc(t: ^testing.T) {
abs_path := "/home/user/project/.env"
cloned_path, _ := strings.clone(abs_path)
dir := filepath.dir(cloned_path)
testing.expect(t, dir == "/home/user/project", "filepath.dir should return parent directory")
testing.expect(t, len(dir) > 0, "dir should not be empty")
cloned_dir, _ := strings.clone(dir)
testing.expect(t, cloned_dir == dir, "clone of dir should equal dir")
}

View File

@@ -121,7 +121,7 @@ next_fd_tmp_path :: proc() -> string {
n := fd_seq n := fd_seq
fd_seq += 1 fd_seq += 1
sync.atomic_mutex_unlock(&fd_counter) sync.atomic_mutex_unlock(&fd_counter)
return fmt.aprintf("/tmp/envr-fd-%d-%d", os.get_pid(), n, allocator = context.temp_allocator) return fmt.tprintf("/tmp/envr-fd-%d-%d", os.get_pid(), n)
} }
cant_scan :: proc(feats: AvailableFeatures) -> bool { cant_scan :: proc(feats: AvailableFeatures) -> bool {

View File

@@ -10,12 +10,12 @@ test_scan_path_finds_gitignored_env_files :: proc(t: ^testing.T) {
feats := check_features() feats := check_features()
testing.expect(t, cant_scan(feats) == false) testing.expect(t, cant_scan(feats) == false)
base := fmt.aprintf("/tmp/envr-scan-test-%d", os.get_pid()) base := fmt.tprintf("/tmp/envr-scan-test-%d", os.get_pid())
os.mkdir_all(base) os.mkdir_all(base)
defer os.remove_all(base) defer os.remove_all(base)
git_init := os.Process_Desc { git_init := os.Process_Desc {
command = []string{"git", "-c", "advice.defaultBranchName=false", "init"}, command = []string{"git", "-c", "advice.defaultBranchName=false", "init", "-q"},
working_dir = base, working_dir = base,
stdout = os.stderr, stdout = os.stderr,
stderr = os.stderr, stderr = os.stderr,
@@ -29,12 +29,12 @@ test_scan_path_finds_gitignored_env_files :: proc(t: ^testing.T) {
return return
} }
gitignore_path := fmt.aprintf("%s/.gitignore", base) gitignore_path := fmt.tprintf("%s/.gitignore", base)
_ = os.write_entire_file(gitignore_path, ".env*\n") _ = os.write_entire_file(gitignore_path, ".env*\n")
_ = os.write_entire_file(fmt.aprintf("%s/.env", base), "SECRET=1") _ = os.write_entire_file(fmt.tprintf("%s/.env", base), "SECRET=1")
_ = os.write_entire_file(fmt.aprintf("%s/.env.testing", base), "TEST=1") _ = os.write_entire_file(fmt.tprintf("%s/.env.testing", base), "TEST=1")
_ = os.write_entire_file(fmt.aprintf("%s/config.yaml", base), "key: value") _ = os.write_entire_file(fmt.tprintf("%s/config.yaml", base), "key: value")
cfg := Config { cfg := Config {
ScanConfig = ScanConfig{Matcher = "\\.env", Exclude = []string{}, Include = []string{}}, ScanConfig = ScanConfig{Matcher = "\\.env", Exclude = []string{}, Include = []string{}},
@@ -71,7 +71,7 @@ test_scan_path_empty_dir :: proc(t: ^testing.T) {
feats := check_features() feats := check_features()
testing.expect(t, cant_scan(feats) == false) testing.expect(t, cant_scan(feats) == false)
base := fmt.aprintf("/tmp/envr-scan-empty-%d", os.get_pid()) base := fmt.tprintf("/tmp/envr-scan-empty-%d", os.get_pid())
os.mkdir_all(base) os.mkdir_all(base)
defer os.remove_all(base) defer os.remove_all(base)
@@ -82,6 +82,6 @@ test_scan_path_empty_dir :: proc(t: ^testing.T) {
results, ok := scan_path(base, cfg) results, ok := scan_path(base, cfg)
defer delete(results) defer delete(results)
testing.expect(t, ok, "scan_path should succeed") testing.expect(t, ok, "scan_path should succeed")
testing.expect(t, len(results) == 0, fmt.aprintf("expected 0 results, got %d", len(results))) testing.expect(t, len(results) == 0, fmt.tprintf("expected 0 results, got %d", len(results)))
} }

View File

@@ -87,11 +87,11 @@ render_json_rows :: proc(w: io.Writer, headers: []string, rows: [][]string) {
append(&entries, entry) append(&entries, entry)
} }
data, err := json.marshal(entries[:]) data, err := json.marshal(entries[:], allocator = context.temp_allocator)
if err != nil { if err != nil {
fmt.eprintf("Error marshaling JSON: %v\n", err) fmt.eprintf("Error marshaling JSON: %v\n", err)
return return
} }
io.write_string(w, string(data)) fmt.wprintf(w, "%s", data, flush = false)
} }

View File

@@ -20,18 +20,18 @@ test_render_json_rows_normal :: proc(t: ^testing.T) {
output := strings.to_string(b) output := strings.to_string(b)
result: []map[string]string result: []map[string]string = ---
unmarshal_err := json.unmarshal_string(output, &result) unmarshal_err := json.unmarshal_string(output, &result, allocator = context.temp_allocator)
testing.expect( testing.expect(
t, t,
unmarshal_err == nil, unmarshal_err == nil,
fmt.aprintf("json unmarshal failed: %v\noutput was: %q", unmarshal_err, output), fmt.tprintf("json unmarshal failed: %v\noutput was: %q", unmarshal_err, output),
) )
testing.expect(t, len(result) == 2, fmt.aprintf("expected 2 rows, got %d", len(result))) testing.expect(t, len(result) == 2, fmt.tprintf("expected 2 rows, got %d", len(result)))
testing.expect( testing.expect(
t, t,
result[0]["name"] == "foo", result[0]["name"] == "foo",
fmt.aprintf("expected name=foo, got %q", result[0]["name"]), fmt.tprintf("expected name=foo, got %q", result[0]["name"]),
) )
testing.expect(t, result[0]["path"] == "/home/user/.env") testing.expect(t, result[0]["path"] == "/home/user/.env")
testing.expect(t, result[1]["name"] == "bar") testing.expect(t, result[1]["name"] == "bar")
@@ -57,18 +57,22 @@ test_render_json_rows_special_chars :: proc(t: ^testing.T) {
output := strings.to_string(b) output := strings.to_string(b)
result: []map[string]string result: []map[string]string = ---
unmarshal_err := json.unmarshal(transmute([]byte)output, &result) unmarshal_err := json.unmarshal(
transmute([]byte)output,
&result,
allocator = context.temp_allocator,
)
testing.expect( testing.expect(
t, t,
unmarshal_err == nil, unmarshal_err == nil,
fmt.aprintf("json unmarshal failed: %v\noutput was: %q", unmarshal_err, output), fmt.tprintf("json unmarshal failed: %v\noutput was: %q", unmarshal_err, output),
) )
testing.expect(t, len(result) == 4) testing.expect(t, len(result) == 4)
testing.expect( testing.expect(
t, t,
result[0]["value"] == `has "double quotes"`, result[0]["value"] == `has "double quotes"`,
fmt.aprintf("got %q", result[0]["value"]), fmt.tprintf("got %q", result[0]["value"]),
) )
testing.expect(t, result[1]["value"] == `path\to\file`) testing.expect(t, result[1]["value"] == `path\to\file`)
testing.expect(t, result[2]["value"] == "line1\nline2") testing.expect(t, result[2]["value"] == "line1\nline2")
@@ -89,12 +93,12 @@ test_render_json_rows_empty :: proc(t: ^testing.T) {
output := strings.to_string(b) output := strings.to_string(b)
result: []map[string]string result: []map[string]string = ---
unmarshal_err := json.unmarshal_string(output, &result) unmarshal_err := json.unmarshal_string(output, &result, allocator = context.temp_allocator)
testing.expect( testing.expect(
t, t,
unmarshal_err == nil, unmarshal_err == nil,
fmt.aprintf("json unmarshal failed: %v\noutput was: %q", unmarshal_err, output), fmt.tprintf("json unmarshal failed: %v\noutput was: %q", unmarshal_err, output),
) )
testing.expect(t, len(result) == 0) testing.expect(t, len(result) == 0)
} }