add support for env variables to the DSL
This commit is contained in:
342
lang/parser_env_test.go
Normal file
342
lang/parser_env_test.go
Normal file
@ -0,0 +1,342 @@
|
||||
package lang
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestServerWithEnvironmentVariables(t *testing.T) {
|
||||
input := `
|
||||
server MyApp {
|
||||
host env "HOST" default "localhost"
|
||||
port env "PORT" default "8080"
|
||||
database_url env "DATABASE_URL" required
|
||||
api_key env "API_SECRET_KEY" required
|
||||
}
|
||||
`
|
||||
|
||||
ast, err := ParseInput(input)
|
||||
if err != nil {
|
||||
t.Fatalf("Parse error: %v", err)
|
||||
}
|
||||
|
||||
if len(ast.Definitions) != 1 {
|
||||
t.Fatalf("Expected 1 definition, got %d", len(ast.Definitions))
|
||||
}
|
||||
|
||||
server := ast.Definitions[0].Server
|
||||
if server == nil {
|
||||
t.Fatalf("Expected server definition")
|
||||
}
|
||||
|
||||
if server.Name != "MyApp" {
|
||||
t.Errorf("Expected server name 'MyApp', got '%s'", server.Name)
|
||||
}
|
||||
|
||||
if len(server.Settings) != 4 {
|
||||
t.Fatalf("Expected 4 settings, got %d", len(server.Settings))
|
||||
}
|
||||
|
||||
// Test host setting
|
||||
hostSetting := server.Settings[0]
|
||||
if hostSetting.Host == nil {
|
||||
t.Fatalf("Expected host setting")
|
||||
}
|
||||
if hostSetting.Host.EnvVar == nil {
|
||||
t.Fatalf("Expected host to be environment variable")
|
||||
}
|
||||
if hostSetting.Host.EnvVar.Name != "HOST" {
|
||||
t.Errorf("Expected env var name 'HOST', got '%s'", hostSetting.Host.EnvVar.Name)
|
||||
}
|
||||
if hostSetting.Host.EnvVar.Default == nil || *hostSetting.Host.EnvVar.Default != "localhost" {
|
||||
t.Errorf("Expected default 'localhost'")
|
||||
}
|
||||
|
||||
// Test port setting
|
||||
portSetting := server.Settings[1]
|
||||
if portSetting.Port == nil {
|
||||
t.Fatalf("Expected port setting")
|
||||
}
|
||||
if portSetting.Port.EnvVar == nil {
|
||||
t.Fatalf("Expected port to be environment variable")
|
||||
}
|
||||
if portSetting.Port.EnvVar.Name != "PORT" {
|
||||
t.Errorf("Expected env var name 'PORT', got '%s'", portSetting.Port.EnvVar.Name)
|
||||
}
|
||||
if portSetting.Port.EnvVar.Default == nil || *portSetting.Port.EnvVar.Default != "8080" {
|
||||
t.Errorf("Expected default '8080'")
|
||||
}
|
||||
|
||||
// Test required database_url
|
||||
dbSetting := server.Settings[2]
|
||||
if dbSetting.DatabaseURL == nil {
|
||||
t.Fatalf("Expected database_url setting")
|
||||
}
|
||||
if dbSetting.DatabaseURL.EnvVar == nil {
|
||||
t.Fatalf("Expected database_url to be environment variable")
|
||||
}
|
||||
if !dbSetting.DatabaseURL.EnvVar.Required {
|
||||
t.Errorf("Expected database_url to be required")
|
||||
}
|
||||
|
||||
// Test required api_key
|
||||
apiSetting := server.Settings[3]
|
||||
if apiSetting.APIKey == nil {
|
||||
t.Fatalf("Expected api_key setting")
|
||||
}
|
||||
if apiSetting.APIKey.EnvVar == nil {
|
||||
t.Fatalf("Expected api_key to be environment variable")
|
||||
}
|
||||
if !apiSetting.APIKey.EnvVar.Required {
|
||||
t.Errorf("Expected api_key to be required")
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerWithMixedValues(t *testing.T) {
|
||||
input := `
|
||||
server MyApp {
|
||||
host "localhost"
|
||||
port env "PORT" default "8080"
|
||||
database_url env "DATABASE_URL" required
|
||||
}
|
||||
`
|
||||
|
||||
ast, err := ParseInput(input)
|
||||
if err != nil {
|
||||
t.Fatalf("Parse error: %v", err)
|
||||
}
|
||||
|
||||
server := ast.Definitions[0].Server
|
||||
if server == nil {
|
||||
t.Fatalf("Expected server definition")
|
||||
}
|
||||
|
||||
// Test literal host
|
||||
hostSetting := server.Settings[0]
|
||||
if hostSetting.Host == nil {
|
||||
t.Fatalf("Expected host setting")
|
||||
}
|
||||
if hostSetting.Host.Literal == nil {
|
||||
t.Fatalf("Expected host to be literal value")
|
||||
}
|
||||
if *hostSetting.Host.Literal != "localhost" {
|
||||
t.Errorf("Expected literal value 'localhost', got '%s'", *hostSetting.Host.Literal)
|
||||
}
|
||||
|
||||
// Test env port
|
||||
portSetting := server.Settings[1]
|
||||
if portSetting.Port == nil {
|
||||
t.Fatalf("Expected port setting")
|
||||
}
|
||||
if portSetting.Port.EnvVar == nil {
|
||||
t.Fatalf("Expected port to be environment variable")
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerWithLiteralPort(t *testing.T) {
|
||||
input := `
|
||||
server MyApp {
|
||||
host "localhost"
|
||||
port 8080
|
||||
}
|
||||
`
|
||||
|
||||
ast, err := ParseInput(input)
|
||||
if err != nil {
|
||||
t.Fatalf("Parse error: %v", err)
|
||||
}
|
||||
|
||||
server := ast.Definitions[0].Server
|
||||
portSetting := server.Settings[1]
|
||||
if portSetting.Port == nil {
|
||||
t.Fatalf("Expected port setting")
|
||||
}
|
||||
if portSetting.Port.Literal == nil {
|
||||
t.Fatalf("Expected port to be literal value")
|
||||
}
|
||||
if *portSetting.Port.Literal != 8080 {
|
||||
t.Errorf("Expected literal port 8080, got %d", *portSetting.Port.Literal)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerConfigurationsInAnyOrder(t *testing.T) {
|
||||
// Test that server settings can be defined in any order
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
}{
|
||||
{
|
||||
name: "host first, then port",
|
||||
input: `
|
||||
server MyApp {
|
||||
host "localhost"
|
||||
port 8080
|
||||
}`,
|
||||
},
|
||||
{
|
||||
name: "port first, then host",
|
||||
input: `
|
||||
server MyApp {
|
||||
port 8080
|
||||
host "localhost"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
name: "mixed literal and env vars in random order",
|
||||
input: `
|
||||
server MyApp {
|
||||
api_key env "API_KEY" required
|
||||
host "localhost"
|
||||
database_url env "DATABASE_URL" default "postgres://localhost:5432/myapp"
|
||||
port 8080
|
||||
ssl_cert env "SSL_CERT" required
|
||||
}`,
|
||||
},
|
||||
{
|
||||
name: "all env vars in different order",
|
||||
input: `
|
||||
server MyApp {
|
||||
ssl_key env "SSL_KEY" required
|
||||
port env "PORT" default "8080"
|
||||
database_url env "DATABASE_URL" required
|
||||
host env "HOST" default "localhost"
|
||||
api_key env "API_KEY" required
|
||||
ssl_cert env "SSL_CERT" required
|
||||
}`,
|
||||
},
|
||||
{
|
||||
name: "all literal values in different order",
|
||||
input: `
|
||||
server MyApp {
|
||||
database_url "postgres://localhost:5432/myapp"
|
||||
port 3000
|
||||
ssl_key "/path/to/ssl.key"
|
||||
host "0.0.0.0"
|
||||
api_key "secret123"
|
||||
ssl_cert "/path/to/ssl.crt"
|
||||
}`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ast, err := ParseInput(tt.input)
|
||||
if err != nil {
|
||||
t.Fatalf("Parse error for %s: %v", tt.name, err)
|
||||
}
|
||||
|
||||
if len(ast.Definitions) != 1 {
|
||||
t.Fatalf("Expected 1 definition, got %d", len(ast.Definitions))
|
||||
}
|
||||
|
||||
server := ast.Definitions[0].Server
|
||||
if server == nil {
|
||||
t.Fatalf("Expected server definition")
|
||||
}
|
||||
|
||||
if server.Name != "MyApp" {
|
||||
t.Errorf("Expected server name 'MyApp', got '%s'", server.Name)
|
||||
}
|
||||
|
||||
// Verify that we can parse any number of settings in any order
|
||||
if len(server.Settings) < 1 {
|
||||
t.Fatalf("Expected at least 1 setting, got %d", len(server.Settings))
|
||||
}
|
||||
|
||||
// Test that we can access specific settings regardless of order
|
||||
var hasHost, hasPort bool
|
||||
for _, setting := range server.Settings {
|
||||
if setting.Host != nil {
|
||||
hasHost = true
|
||||
}
|
||||
if setting.Port != nil {
|
||||
hasPort = true
|
||||
}
|
||||
}
|
||||
|
||||
// For the first two tests, verify both host and port are present
|
||||
if tt.name == "host first, then port" || tt.name == "port first, then host" {
|
||||
if !hasHost {
|
||||
t.Errorf("Expected to find host setting")
|
||||
}
|
||||
if !hasPort {
|
||||
t.Errorf("Expected to find port setting")
|
||||
}
|
||||
}
|
||||
|
||||
t.Logf("Successfully parsed %d settings for test '%s'", len(server.Settings), tt.name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerConfigurationValidation(t *testing.T) {
|
||||
// Test that we can properly validate different configurations
|
||||
input := `
|
||||
server ProductionApp {
|
||||
ssl_cert env "SSL_CERT_PATH" required
|
||||
database_url env "DATABASE_URL" required
|
||||
host env "HOST" default "0.0.0.0"
|
||||
api_key env "SECRET_API_KEY" required
|
||||
port env "PORT" default "443"
|
||||
ssl_key env "SSL_KEY_PATH" required
|
||||
}
|
||||
`
|
||||
|
||||
ast, err := ParseInput(input)
|
||||
if err != nil {
|
||||
t.Fatalf("Parse error: %v", err)
|
||||
}
|
||||
|
||||
server := ast.Definitions[0].Server
|
||||
if server.Name != "ProductionApp" {
|
||||
t.Errorf("Expected server name 'ProductionApp', got '%s'", server.Name)
|
||||
}
|
||||
|
||||
// Create a map to easily check for specific settings
|
||||
settingsMap := make(map[string]interface{})
|
||||
for _, setting := range server.Settings {
|
||||
if setting.Host != nil {
|
||||
settingsMap["host"] = setting.Host
|
||||
}
|
||||
if setting.Port != nil {
|
||||
settingsMap["port"] = setting.Port
|
||||
}
|
||||
if setting.DatabaseURL != nil {
|
||||
settingsMap["database_url"] = setting.DatabaseURL
|
||||
}
|
||||
if setting.APIKey != nil {
|
||||
settingsMap["api_key"] = setting.APIKey
|
||||
}
|
||||
if setting.SSLCert != nil {
|
||||
settingsMap["ssl_cert"] = setting.SSLCert
|
||||
}
|
||||
if setting.SSLKey != nil {
|
||||
settingsMap["ssl_key"] = setting.SSLKey
|
||||
}
|
||||
}
|
||||
|
||||
// Verify all expected settings are present
|
||||
expectedSettings := []string{"host", "port", "database_url", "api_key", "ssl_cert", "ssl_key"}
|
||||
for _, expected := range expectedSettings {
|
||||
if _, exists := settingsMap[expected]; !exists {
|
||||
t.Errorf("Expected to find setting '%s'", expected)
|
||||
}
|
||||
}
|
||||
|
||||
// Verify host has default value
|
||||
if hostSetting, ok := settingsMap["host"].(*ConfigValue); ok {
|
||||
if hostSetting.EnvVar == nil {
|
||||
t.Errorf("Expected host to be environment variable")
|
||||
} else if hostSetting.EnvVar.Default == nil || *hostSetting.EnvVar.Default != "0.0.0.0" {
|
||||
t.Errorf("Expected host default to be '0.0.0.0'")
|
||||
}
|
||||
}
|
||||
|
||||
// Verify ssl_cert is required
|
||||
if sslCertSetting, ok := settingsMap["ssl_cert"].(*ConfigValue); ok {
|
||||
if sslCertSetting.EnvVar == nil {
|
||||
t.Errorf("Expected ssl_cert to be environment variable")
|
||||
} else if !sslCertSetting.EnvVar.Required {
|
||||
t.Errorf("Expected ssl_cert to be required")
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user