mirror of
https://github.com/sbrow/envr.git
synced 2026-06-27 10:38:33 -04:00
321 lines
8.0 KiB
Odin
321 lines
8.0 KiB
Odin
package findr
|
|
|
|
import "core:os"
|
|
import "core:sort"
|
|
import "core:strings"
|
|
import "core:sys/linux"
|
|
import "core:testing"
|
|
|
|
// ============================================================================
|
|
// Gitignored file emission tests (emit ONLY gitignored files, descend everywhere)
|
|
// ============================================================================
|
|
|
|
@(test)
|
|
test_basic_gitignored :: proc(t: ^testing.T) {
|
|
env := create_test_env()
|
|
defer destroy_test_env(&env)
|
|
|
|
create_git_repo(env, "repo")
|
|
create_file(env, "repo/.gitignore", "*.env\n")
|
|
create_file(env, "repo/.env")
|
|
create_file(env, "repo/secrets.env")
|
|
create_file(env, "repo/normal.txt")
|
|
|
|
assert_output(t, env, nil, {}, {
|
|
"repo/.env", "repo/secrets.env",
|
|
})
|
|
}
|
|
|
|
@(test)
|
|
test_non_repo_not_scanned :: proc(t: ^testing.T) {
|
|
env := create_test_env()
|
|
defer destroy_test_env(&env)
|
|
|
|
create_dir(env, "norepo")
|
|
create_file(env, "norepo/.gitignore", "*.env\n")
|
|
create_file(env, "norepo/.env")
|
|
|
|
assert_output_empty(t, env, nil, {})
|
|
}
|
|
|
|
@(test)
|
|
test_negation_pattern :: proc(t: ^testing.T) {
|
|
env := create_test_env()
|
|
defer destroy_test_env(&env)
|
|
|
|
create_git_repo(env, "repo")
|
|
create_file(env, "repo/.gitignore", "*.env\n!prod.env\n")
|
|
create_file(env, "repo/.env")
|
|
create_file(env, "repo/secrets.env")
|
|
create_file(env, "repo/prod.env")
|
|
|
|
assert_output(t, env, nil, {}, {
|
|
"repo/.env", "repo/secrets.env",
|
|
})
|
|
}
|
|
|
|
@(test)
|
|
test_multiple_repos :: proc(t: ^testing.T) {
|
|
env := create_test_env()
|
|
defer destroy_test_env(&env)
|
|
|
|
create_git_repo(env, "repo1")
|
|
create_file(env, "repo1/.gitignore", "*.env\n")
|
|
create_file(env, "repo1/a.env")
|
|
|
|
create_git_repo(env, "repo2")
|
|
create_file(env, "repo2/.gitignore", "*.key\n")
|
|
create_file(env, "repo2/secret.key")
|
|
|
|
assert_output(t, env, nil, {}, {
|
|
"repo1/a.env", "repo2/secret.key",
|
|
})
|
|
}
|
|
|
|
@(test)
|
|
test_nested_repos :: proc(t: ^testing.T) {
|
|
env := create_test_env()
|
|
defer destroy_test_env(&env)
|
|
|
|
create_git_repo(env, "parent")
|
|
create_file(env, "parent/.gitignore", "*.env\n")
|
|
create_file(env, "parent/top.env")
|
|
|
|
create_git_repo(env, "parent/child")
|
|
create_file(env, "parent/child/.gitignore", "*.key\n")
|
|
create_file(env, "parent/child/api.key")
|
|
|
|
assert_output(t, env, nil, {}, {
|
|
"parent/top.env", "parent/child/api.key",
|
|
})
|
|
}
|
|
|
|
@(test)
|
|
test_nested_gitignore_read :: proc(t: ^testing.T) {
|
|
env := create_test_env()
|
|
defer destroy_test_env(&env)
|
|
|
|
create_git_repo(env, "repo")
|
|
create_file(env, "repo/.gitignore", "*.env\n")
|
|
create_dir(env, "repo/sub")
|
|
create_file(env, "repo/sub/.gitignore", "*.txt\n")
|
|
create_file(env, "repo/sub/secret.txt")
|
|
create_file(env, "repo/sub/.env")
|
|
|
|
assert_output(t, env, nil, {}, {
|
|
"repo/sub/secret.txt", "repo/sub/.env",
|
|
})
|
|
}
|
|
|
|
@(test)
|
|
test_nested_gitignore_negation :: proc(t: ^testing.T) {
|
|
env := create_test_env()
|
|
defer destroy_test_env(&env)
|
|
|
|
create_git_repo(env, "repo")
|
|
create_file(env, "repo/.gitignore", "*.log\n")
|
|
create_dir(env, "repo/sub")
|
|
create_file(env, "repo/sub/.gitignore", "!important.log\n")
|
|
create_file(env, "repo/sub/important.log")
|
|
create_file(env, "repo/sub/debug.log")
|
|
|
|
assert_output(t, env, nil, {}, {
|
|
"repo/sub/debug.log",
|
|
})
|
|
}
|
|
|
|
@(test)
|
|
test_multisegment_pattern :: proc(t: ^testing.T) {
|
|
env := create_test_env()
|
|
defer destroy_test_env(&env)
|
|
|
|
create_git_repo(env, "repo")
|
|
create_file(env, "repo/.gitignore", "build/output.txt\n")
|
|
create_dir(env, "repo/build")
|
|
create_file(env, "repo/build/output.txt")
|
|
create_file(env, "repo/build/other.txt")
|
|
create_file(env, "repo/output.txt")
|
|
|
|
assert_output(t, env, nil, {}, {
|
|
"repo/build/output.txt",
|
|
})
|
|
}
|
|
|
|
@(test)
|
|
test_no_gitignore_file :: proc(t: ^testing.T) {
|
|
env := create_test_env()
|
|
defer destroy_test_env(&env)
|
|
|
|
create_git_repo(env, "repo")
|
|
create_file(env, "repo/.env")
|
|
|
|
assert_output_empty(t, env, nil, {})
|
|
}
|
|
|
|
@(test)
|
|
test_empty_gitignore :: proc(t: ^testing.T) {
|
|
env := create_test_env()
|
|
defer destroy_test_env(&env)
|
|
|
|
create_git_repo(env, "repo")
|
|
create_file(env, "repo/.gitignore", "\n\n# comment\n\n")
|
|
create_file(env, "repo/.env")
|
|
|
|
assert_output_empty(t, env, nil, {})
|
|
}
|
|
|
|
@(test)
|
|
test_multiple_search_dirs :: proc(t: ^testing.T) {
|
|
env := create_test_env()
|
|
defer destroy_test_env(&env)
|
|
|
|
create_git_repo(env, "dir1/repo")
|
|
create_file(env, "dir1/repo/.gitignore", "*.env\n")
|
|
create_file(env, "dir1/repo/a.env")
|
|
create_file(env, "dir1/repo/normal.txt")
|
|
|
|
create_git_repo(env, "dir2/repo")
|
|
create_file(env, "dir2/repo/.gitignore", "*.env\n")
|
|
create_file(env, "dir2/repo/b.env")
|
|
|
|
dir1 := join_path(env.temp_dir, "dir1")
|
|
defer delete(dir1)
|
|
dir2 := join_path(env.temp_dir, "dir2")
|
|
defer delete(dir2)
|
|
|
|
results := make([dynamic]string)
|
|
defer {
|
|
for r in results {delete(r)}
|
|
delete(results)
|
|
}
|
|
|
|
opts := WalkOptions{}
|
|
thread_count := os.get_processor_core_count()
|
|
walk({dir1, dir2}, &results, opts, thread_count)
|
|
|
|
testing.expect_value(t, len(results), 2)
|
|
|
|
actual := make([dynamic]string, 0, len(results))
|
|
for r in results {
|
|
stripped := r
|
|
if strings.has_prefix(stripped, env.temp_dir) {
|
|
stripped = stripped[len(env.temp_dir):]
|
|
if len(stripped) > 0 && stripped[0] == '/' {
|
|
stripped = stripped[1:]
|
|
}
|
|
}
|
|
append(&actual, stripped)
|
|
}
|
|
defer delete(actual)
|
|
|
|
expected := []string{"dir1/repo/a.env", "dir2/repo/b.env"}
|
|
|
|
sort.quick_sort(actual[:])
|
|
sort.quick_sort(expected[:])
|
|
|
|
for i in 0 ..< len(expected) {
|
|
testing.expect_value(t, actual[i], expected[i])
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Ignored directory recursion tests
|
|
// ============================================================================
|
|
|
|
@(test)
|
|
test_ignored_dir_descended :: proc(t: ^testing.T) {
|
|
env := create_test_env()
|
|
defer destroy_test_env(&env)
|
|
|
|
create_git_repo(env, "repo")
|
|
create_file(env, "repo/.gitignore", "secrets/\n")
|
|
create_dir(env, "repo/secrets")
|
|
create_file(env, "repo/secrets/.env")
|
|
create_file(env, "repo/secrets/api.key")
|
|
|
|
// Ignored dir's contents are emitted AND descended into
|
|
assert_output(t, env, nil, {}, {
|
|
"repo/secrets/", "repo/secrets/.env", "repo/secrets/api.key",
|
|
})
|
|
}
|
|
|
|
@(test)
|
|
test_nested_ignored_dir :: proc(t: ^testing.T) {
|
|
env := create_test_env()
|
|
defer destroy_test_env(&env)
|
|
|
|
create_git_repo(env, "repo")
|
|
create_file(env, "repo/.gitignore", "build/\n")
|
|
create_dir(env, "repo/build")
|
|
create_dir(env, "repo/build/sub")
|
|
create_file(env, "repo/build/output.txt")
|
|
create_file(env, "repo/build/sub/deep.env")
|
|
|
|
assert_output(t, env, nil, {}, {
|
|
"repo/build/", "repo/build/output.txt",
|
|
"repo/build/sub/", "repo/build/sub/deep.env",
|
|
})
|
|
}
|
|
|
|
// ============================================================================
|
|
// Filter tests (excludes, pattern)
|
|
// ============================================================================
|
|
|
|
@(test)
|
|
test_excludes_prune_dirs :: proc(t: ^testing.T) {
|
|
env := create_test_env()
|
|
defer destroy_test_env(&env)
|
|
|
|
create_git_repo(env, "repo")
|
|
create_file(env, "repo/.gitignore", "*.env\n")
|
|
create_file(env, "repo/.env")
|
|
create_dir(env, "repo/vendor")
|
|
create_file(env, "repo/vendor/lib.env")
|
|
|
|
assert_output(t, env, nil,
|
|
{excludes = {"vendor"}},
|
|
{"repo/.env"},
|
|
)
|
|
}
|
|
|
|
@(test)
|
|
test_pattern_filters_results :: proc(t: ^testing.T) {
|
|
env := create_test_env()
|
|
defer destroy_test_env(&env)
|
|
|
|
create_git_repo(env, "repo")
|
|
create_file(env, "repo/.gitignore", "*.env\n*.key\n")
|
|
create_file(env, "repo/.env")
|
|
create_file(env, "repo/secrets.env")
|
|
create_file(env, "repo/master.key")
|
|
|
|
assert_output(t, env, nil,
|
|
{pattern = "\\.env$"},
|
|
{"repo/.env", "repo/secrets.env"},
|
|
)
|
|
}
|
|
|
|
// ============================================================================
|
|
// Special file type tests
|
|
// ============================================================================
|
|
|
|
@(test)
|
|
test_fifo_emitted :: proc(t: ^testing.T) {
|
|
env := create_test_env()
|
|
defer destroy_test_env(&env)
|
|
|
|
create_git_repo(env, "repo")
|
|
create_file(env, "repo/.gitignore", "*.env\n*.fifo\n")
|
|
|
|
fifo_path := join_path(env.temp_dir, "repo/test.fifo")
|
|
defer delete(fifo_path)
|
|
cpath := strings.clone_to_cstring(fifo_path)
|
|
defer delete(cpath)
|
|
linux.mknod(cpath, linux.S_IFIFO | linux.Mode{.IRUSR, .IWUSR}, 0)
|
|
|
|
assert_output(t, env, nil,
|
|
{pattern = "\\.fifo$"},
|
|
{"repo/test.fifo"},
|
|
)
|
|
}
|