Files
goget/internal/config/config_test.go

339 lines
8.8 KiB
Go

//go:build linux || freebsd
// +build linux freebsd
package config
import (
"strings"
"testing"
"time"
"codeberg.org/petrbalvin/interpres"
)
func TestDefaultConfig(t *testing.T) {
cfg := DefaultConfig()
if cfg.Timeout != 30*time.Minute {
t.Errorf("Expected default timeout 30m, got %v", cfg.Timeout)
}
if cfg.Parallel != 0 {
t.Errorf("Expected default parallel 0, got %d", cfg.Parallel)
}
if cfg.Verbose != true {
t.Errorf("Expected default verbose true, got %v", cfg.Verbose)
}
if cfg.AutoDecompress != true {
t.Errorf("Expected default auto decompress true, got %v", cfg.AutoDecompress)
}
if cfg.ChecksumAlgo != "sha256" {
t.Errorf("Expected default checksum algo sha256, got %s", cfg.ChecksumAlgo)
}
}
func TestConfigMerge(t *testing.T) {
cfg := DefaultConfig()
cfg.Merge(&CLIFlags{
Timeout: 1 * time.Hour,
Parallel: 4,
Verbose: true,
Debug: false,
MaxSpeed: 1024 * 1024,
Proxy: "http://proxy",
NoIPv4: false,
NoDecompress: false,
Username: "user",
Password: "pass",
CookieJar: "",
Recursive: false,
MaxDepth: 0,
FollowExternal: false,
ExcludePatterns: nil,
Extract: false,
ExtractDir: "",
StripComponents: 0,
})
if cfg.Timeout != 1*time.Hour {
t.Errorf("Expected timeout 1h, got %v", cfg.Timeout)
}
if cfg.Parallel != 4 {
t.Errorf("Expected parallel 4, got %d", cfg.Parallel)
}
if cfg.Proxy != "http://proxy" {
t.Errorf("Expected proxy http://proxy, got %s", cfg.Proxy)
}
if cfg.Auth.Username != "user" {
t.Errorf("Expected username user, got %s", cfg.Auth.Username)
}
}
func TestGetEffectiveTimeout(t *testing.T) {
cfg := DefaultConfig()
// User override
timeout := cfg.GetEffectiveTimeout(1000000, 1*time.Hour)
if timeout != 1*time.Hour {
t.Errorf("Expected 1h with user override, got %v", timeout)
}
// Auto calculation for known size
timeout = cfg.GetEffectiveTimeout(100*1024*1024, 0)
if timeout < 30*time.Second {
t.Errorf("Expected at least 30s for auto timeout, got %v", timeout)
}
// Unknown size
timeout = cfg.GetEffectiveTimeout(-1, 0)
if timeout != 30*time.Minute {
t.Errorf("Expected 30m for unknown size, got %v", timeout)
}
}
func TestGetParallelConnections(t *testing.T) {
cfg := DefaultConfig()
// Explicit parallel
cfg.Parallel = 8
if cfg.GetParallelConnections(1000) != 8 {
t.Errorf("Expected 8 explicit connections, got %d", cfg.GetParallelConnections(1000))
}
// Auto for large file
cfg.Parallel = 0
if cfg.GetParallelConnections(200*1024*1024) != 4 {
t.Errorf("Expected 4 auto connections for large file, got %d", cfg.GetParallelConnections(200*1024*1024))
}
// Auto for small file
if cfg.GetParallelConnections(1024) != 1 {
t.Errorf("Expected 1 connection for small file, got %d", cfg.GetParallelConnections(1024))
}
}
func TestShouldUseColors(t *testing.T) {
cfg := DefaultConfig()
// Always
cfg.Color = "always"
if !cfg.ShouldUseColors() {
t.Error("Expected colors with always setting")
}
// Never
cfg.Color = "never"
if cfg.ShouldUseColors() {
t.Error("Expected no colors with never setting")
}
// Auto (default)
cfg.Color = "auto"
// Can't test environment in unit tests, but verify it doesn't panic
_ = cfg.ShouldUseColors()
}
func TestIsExcluded(t *testing.T) {
cfg := DefaultConfig()
cfg.Recursive.ExcludePatterns = []string{"example.com", "test.org"}
if !cfg.IsExcluded("https://example.com/file.zip") {
t.Error("Expected example.com to be excluded")
}
if !cfg.IsExcluded("https://test.org/file.zip") {
t.Error("Expected test.org to be excluded")
}
if cfg.IsExcluded("https://other.com/file.zip") {
t.Error("Expected other.com to not be excluded")
}
}
func TestGetRecursiveDelay(t *testing.T) {
cfg := DefaultConfig()
delay := cfg.GetRecursiveDelay()
if delay != 100*time.Millisecond {
t.Errorf("Expected default delay 100ms, got %v", delay)
}
cfg.Recursive.Delay = "500ms"
delay = cfg.GetRecursiveDelay()
if delay != 500*time.Millisecond {
t.Errorf("Expected delay 500ms, got %v", delay)
}
// Invalid delay should fall back to default
cfg.Recursive.Delay = "invalid"
delay = cfg.GetRecursiveDelay()
if delay != 100*time.Millisecond {
t.Errorf("Expected default delay for invalid value, got %v", delay)
}
}
func TestGetExtractOutputDir(t *testing.T) {
cfg := DefaultConfig()
// Empty config should return default
dir := cfg.GetExtractOutputDir("/default")
if dir != "/default" {
t.Errorf("Expected /default, got %s", dir)
}
// Config with output dir
cfg.Extract.OutputDir = "/custom"
dir = cfg.GetExtractOutputDir("/default")
if dir != "/custom" {
t.Errorf("Expected /custom, got %s", dir)
}
}
func TestParseSpeed(t *testing.T) {
tests := []struct {
input string
expected int64
}{
{"", 0},
{"0", 0},
{"100", 100},
{"100B/s", 100},
{"1KB/s", 1000},
{"1MB/s", 1000000},
{"1GB/s", 1000000000},
{"10MB/s", 10000000},
{"100 KB/s", 100000},
}
for _, test := range tests {
result := ParseSpeed(test.input)
if result != test.expected {
t.Errorf("ParseSpeed(%s) = %d, expected %d", test.input, result, test.expected)
}
}
}
func TestExpandTilde(t *testing.T) {
// Test with tilde
path := expandTilde("~/test/file.txt")
if path == "~/test/file.txt" {
t.Error("Expected tilde to be expanded")
}
// Test without tilde
path = expandTilde("/absolute/path/file.txt")
if path != "/absolute/path/file.txt" {
t.Errorf("Expected unchanged path, got %s", path)
}
}
func TestConfigSave(t *testing.T) {
cfg := DefaultConfig()
cfg.Verbose = true
cfg.Parallel = 4
// Save should not fail (may create directories)
err := cfg.Save()
// We can't test the actual file creation in unit tests without a temp dir
// but we verify the method doesn't panic
_ = err
}
func TestLoadNonExistentConfig(t *testing.T) {
cfg, err := Load("/nonexistent/path/config.toml")
if err != nil {
t.Fatalf("Expected no error for non-existent config, got %v", err)
}
if cfg == nil {
t.Fatal("Expected default config for non-existent file")
}
}
func TestMarshalUnmarshalTOML(t *testing.T) {
cfg := DefaultConfig()
cfg.Parallel = 4
cfg.Verbose = true
cfg.Timeout = 5 * time.Minute
cfg.Auth.Username = "testuser"
cfg.Auth.AuthType = "basic"
cfg.Recursive.Enabled = true
cfg.Recursive.MaxDepth = 5
cfg.DNSServers = []string{"1.1.1.1", "8.8.8.8"}
data, err := interpres.Marshal(*cfg)
if err != nil {
t.Fatalf("interpres.Marshal failed: %v", err)
}
tomlStr := string(data)
// Verify key elements are present
if !strings.Contains(tomlStr, "parallel = 4") {
t.Errorf("expected 'parallel = 4' in TOML output, got:\n%s", tomlStr)
}
if !strings.Contains(tomlStr, "verbose = true") {
t.Errorf("expected 'verbose = true' in TOML output, got:\n%s", tomlStr)
}
if !strings.Contains(tomlStr, "[auth]") {
t.Errorf("expected '[auth]' section in TOML output, got:\n%s", tomlStr)
}
if !strings.Contains(tomlStr, "username = \"testuser\"") {
t.Errorf("expected 'username = \"testuser\"' in TOML output, got:\n%s", tomlStr)
}
if !strings.Contains(tomlStr, "[recursive]") {
t.Errorf("expected '[recursive]' section in TOML output, got:\n%s", tomlStr)
}
if !strings.Contains(tomlStr, "dns_servers = [") {
t.Errorf("expected 'dns_servers' array in TOML output, got:\n%s", tomlStr)
}
// Roundtrip: unmarshal back and verify
var cfg2 Config
if err := interpres.Unmarshal(data, &cfg2); err != nil {
t.Fatalf("interpres.Unmarshal failed: %v", err)
}
if cfg2.Parallel != 4 {
t.Errorf("roundtrip: expected Parallel 4, got %d", cfg2.Parallel)
}
if cfg2.Verbose != true {
t.Errorf("roundtrip: expected Verbose true, got %v", cfg2.Verbose)
}
if cfg2.Auth.Username != "testuser" {
t.Errorf("roundtrip: expected Auth.Username testuser, got %s", cfg2.Auth.Username)
}
if cfg2.Recursive.MaxDepth != 5 {
t.Errorf("roundtrip: expected Recursive.MaxDepth 5, got %d", cfg2.Recursive.MaxDepth)
}
if len(cfg2.DNSServers) != 2 || cfg2.DNSServers[0] != "1.1.1.1" {
t.Errorf("roundtrip: expected DNSServers [1.1.1.1, 8.8.8.8], got %v", cfg2.DNSServers)
}
}
func TestMarshalTOMLDefaultConfig(t *testing.T) {
cfg := DefaultConfig()
data, err := interpres.Marshal(*cfg)
if err != nil {
t.Fatalf("interpres.Marshal with default config failed: %v", err)
}
if len(data) == 0 {
t.Error("expected non-empty TOML output for default config")
}
// Verify it can be parsed back
var cfg2 Config
if err := interpres.Unmarshal(data, &cfg2); err != nil {
t.Fatalf("interpres.Unmarshal of default output failed: %v", err)
}
if cfg2.OutputDir != "." {
t.Errorf("expected OutputDir '.', got %s", cfg2.OutputDir)
}
if cfg2.ChecksumAlgo != "sha256" {
t.Errorf("expected ChecksumAlgo sha256, got %s", cfg2.ChecksumAlgo)
}
}
func TestConfigPath(t *testing.T) {
cfg := DefaultConfig()
path := cfg.Path()
// Path should be empty when loaded with DefaultConfig
_ = path
}