Files
masonry/lang/parser_env_test.go

343 lines
8.5 KiB
Go

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")
}
}
}