ebf246beb0
- dotenv_load: parser .env con no-sobreescritura y soporte de comillas - env_require: os.Getenv con error descriptivo fail-fast - env_require_all: verifica multiples vars y lista todas las faltantes - config_from_env: reflection sobre struct tags env/default/required/secret, 5 tipos soportados - config_from_file: JSON via stdlib, YAML stub con not-implemented - 25 tests unitarios, todos PASS Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
98 lines
2.6 KiB
Go
98 lines
2.6 KiB
Go
package infra
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func TestDotenvLoad(t *testing.T) {
|
|
// helper to write a temp .env file
|
|
writeEnv := func(t *testing.T, content string) string {
|
|
t.Helper()
|
|
dir := t.TempDir()
|
|
p := filepath.Join(dir, ".env")
|
|
if err := os.WriteFile(p, []byte(content), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return p
|
|
}
|
|
|
|
t.Run("parsea KEY=VALUE y setea variable", func(t *testing.T) {
|
|
p := writeEnv(t, "DOTENV_TEST_FOO=hello\n")
|
|
t.Setenv("DOTENV_TEST_FOO", "") // ensure unset
|
|
os.Unsetenv("DOTENV_TEST_FOO")
|
|
|
|
if err := DotenvLoad(p); err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if got := os.Getenv("DOTENV_TEST_FOO"); got != "hello" {
|
|
t.Errorf("expected DOTENV_TEST_FOO=hello, got %q", got)
|
|
}
|
|
})
|
|
|
|
t.Run("ignora lineas comentario y vacias", func(t *testing.T) {
|
|
content := "# this is a comment\n\nDOTENV_TEST_BAR=world\n"
|
|
p := writeEnv(t, content)
|
|
os.Unsetenv("DOTENV_TEST_BAR")
|
|
|
|
if err := DotenvLoad(p); err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if got := os.Getenv("DOTENV_TEST_BAR"); got != "world" {
|
|
t.Errorf("expected world, got %q", got)
|
|
}
|
|
})
|
|
|
|
t.Run("no sobreescribe variables ya seteadas", func(t *testing.T) {
|
|
p := writeEnv(t, "DOTENV_TEST_EXISTING=new\n")
|
|
t.Setenv("DOTENV_TEST_EXISTING", "original")
|
|
|
|
if err := DotenvLoad(p); err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if got := os.Getenv("DOTENV_TEST_EXISTING"); got != "original" {
|
|
t.Errorf("expected original (not overwritten), got %q", got)
|
|
}
|
|
})
|
|
|
|
t.Run("valores con comillas dobles se stripean", func(t *testing.T) {
|
|
p := writeEnv(t, `DOTENV_TEST_QUOTED="quoted value"`)
|
|
os.Unsetenv("DOTENV_TEST_QUOTED")
|
|
|
|
if err := DotenvLoad(p); err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if got := os.Getenv("DOTENV_TEST_QUOTED"); got != "quoted value" {
|
|
t.Errorf("expected 'quoted value', got %q", got)
|
|
}
|
|
})
|
|
|
|
t.Run("valores con comillas simples se stripean", func(t *testing.T) {
|
|
p := writeEnv(t, "DOTENV_TEST_SINGLE='single quoted'")
|
|
os.Unsetenv("DOTENV_TEST_SINGLE")
|
|
|
|
if err := DotenvLoad(p); err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if got := os.Getenv("DOTENV_TEST_SINGLE"); got != "single quoted" {
|
|
t.Errorf("expected 'single quoted', got %q", got)
|
|
}
|
|
})
|
|
|
|
t.Run("archivo inexistente retorna error", func(t *testing.T) {
|
|
err := DotenvLoad("/nonexistent/.env.does.not.exist")
|
|
if err == nil {
|
|
t.Error("expected error for missing file")
|
|
}
|
|
})
|
|
|
|
t.Run("linea sin signo igual retorna error", func(t *testing.T) {
|
|
p := writeEnv(t, "INVALID_LINE\n")
|
|
err := DotenvLoad(p)
|
|
if err == nil {
|
|
t.Error("expected error for line without '='")
|
|
}
|
|
})
|
|
}
|