Skip to main content
Glama
ConfigurationTests.swift9.75 kB
import Foundation import Testing @testable import PeekabooCLI @Suite("Configuration Tests", .tags(.unit), .serialized) struct ConfigurationTests { // MARK: - JSONC Parser Tests @Test("Strip single-line comments from JSONC", .tags(.fast)) func stripSingleLineComments() throws { let manager = ConfigurationManager.shared let jsonc = """ { // This is a comment "key": "value", // Another comment "number": 42 } """ let result = manager.stripJSONComments(from: jsonc) let data = Data(result.utf8) let parsed = try Self.decodedDictionary(from: data) #expect(parsed["key"] as? String == "value") #expect(parsed["number"] as? Int == 42) } @Test("Strip multi-line comments from JSONC", .tags(.fast)) func stripMultiLineComments() throws { let manager = ConfigurationManager.shared let jsonc = """ { /* This is a multi-line comment */ "key": "value", /* Another comment */ "number": 42 } """ let result = manager.stripJSONComments(from: jsonc) let data = Data(result.utf8) let parsed = try Self.decodedDictionary(from: data) #expect(parsed["key"] as? String == "value") #expect(parsed["number"] as? Int == 42) } @Test("Preserve comments inside strings", .tags(.fast)) func preserveCommentsInStrings() throws { let manager = ConfigurationManager.shared let jsonc = """ { "url": "http://example.com//path", "comment": "This // is not a comment", "multiline": "This /* is also */ not a comment" } """ let result = manager.stripJSONComments(from: jsonc) let data = Data(result.utf8) let parsed = try Self.decodedDictionary(from: data) #expect(parsed["url"] as? String == "http://example.com//path") #expect(parsed["comment"] as? String == "This // is not a comment") #expect(parsed["multiline"] as? String == "This /* is also */ not a comment") } // MARK: - Environment Variable Expansion Tests @Test("Expand environment variables", .tags(.fast)) func expandEnvironmentVariables() throws { let manager = ConfigurationManager.shared // Set test environment variables setenv("TEST_VAR", "test_value", 1) setenv("ANOTHER_VAR", "another_value", 1) let text = """ { "key1": "${TEST_VAR}", "key2": "prefix_${ANOTHER_VAR}_suffix", "key3": "${UNDEFINED_VAR}" } """ let result = manager.expandEnvironmentVariables(in: text) #expect(result.contains("\"test_value\"")) #expect(result.contains("prefix_another_value_suffix")) let containsUndefinedVar = result.contains("${UNDEFINED_VAR}") #expect(containsUndefinedVar) // Undefined vars should remain as-is // Clean up unsetenv("TEST_VAR") unsetenv("ANOTHER_VAR") } // MARK: - Configuration Value Precedence Tests @Test("Configuration value precedence", .tags(.fast)) func configurationPrecedence() { let manager = ConfigurationManager.shared // Test precedence: CLI > env > config > default // CLI value takes highest precedence let cliResult = manager.getValue( cliValue: "cli_value", envVar: nil, configValue: "config_value", defaultValue: "default_value" ) #expect(cliResult == "cli_value") // Environment variable takes second precedence setenv("TEST_ENV_VAR", "env_value", 1) let envResult = manager.getValue( cliValue: nil as String?, envVar: "TEST_ENV_VAR", configValue: "config_value", defaultValue: "default_value" ) #expect(envResult == "env_value") unsetenv("TEST_ENV_VAR") // Config value takes third precedence let configResult = manager.getValue( cliValue: nil as String?, envVar: "UNDEFINED_VAR", configValue: "config_value", defaultValue: "default_value" ) #expect(configResult == "config_value") // Default value as fallback let defaultResult = manager.getValue( cliValue: nil as String?, envVar: "UNDEFINED_VAR", configValue: nil as String?, defaultValue: "default_value" ) #expect(defaultResult == "default_value") } // MARK: - Configuration Loading Tests @Test("Parse valid configuration", .tags(.fast)) func parseValidConfiguration() throws { let json = """ { "aiProviders": { "providers": "openai/gpt-5.1,anthropic/claude-sonnet-4.5", "openaiApiKey": "test_key", "anthropicApiKey": "test_claude_key" }, "defaults": { "savePath": "~/Desktop/Screenshots", "imageFormat": "png", "captureMode": "window", "captureFocus": "auto" }, "logging": { "level": "debug", "path": "/tmp/peekaboo.log" } } """ let data = Data(json.utf8) let config = try JSONDecoder().decode(Configuration.self, from: data) #expect(config.aiProviders?.providers == "openai/gpt-5.1,anthropic/claude-sonnet-4.5") #expect(config.aiProviders?.openaiApiKey == "test_key") #expect(config.aiProviders?.anthropicApiKey == "test_claude_key") #expect(config.defaults?.savePath == "~/Desktop/Screenshots") #expect(config.defaults?.imageFormat == "png") #expect(config.defaults?.captureMode == "window") #expect(config.defaults?.captureFocus == "auto") #expect(config.logging?.level == "debug") #expect(config.logging?.path == "/tmp/peekaboo.log") } @Test("Parse partial configuration", .tags(.fast)) func parsePartialConfiguration() throws { let json = """ { "aiProviders": { "providers": "anthropic/claude-sonnet-4.5" } } """ let data = Data(json.utf8) let config = try JSONDecoder().decode(Configuration.self, from: data) #expect(config.aiProviders?.providers == "anthropic/claude-sonnet-4.5") #expect(config.aiProviders?.openaiApiKey == nil) #expect(config.defaults == nil) #expect(config.logging == nil) } // MARK: - Path Expansion Tests @Test("Expand tilde in paths", .tags(.fast)) func expandTildeInPaths() { let manager = ConfigurationManager.shared let path = manager.getDefaultSavePath(cliValue: "~/Desktop/Screenshots") #expect(path.hasPrefix("/")) #expect(!path.contains("~")) #expect(path.contains("Desktop/Screenshots")) } // MARK: - Integration Tests @Test("Get AI providers with configuration", .tags(.fast)) func getAIProvidersWithConfig() { let manager = ConfigurationManager.shared // Capture baseline (may include persisted user configuration) let baselineProviders = manager.getAIProviders(cliValue: nil) #expect(!baselineProviders.isEmpty) // Test with CLI value let cliProviders = manager.getAIProviders(cliValue: "openai/gpt-5.1") #expect(cliProviders == "openai/gpt-5.1") // Test with environment variable setenv("PEEKABOO_AI_PROVIDERS", "env_provider", 1) let envProviders = manager.getAIProviders(cliValue: nil) #expect(envProviders == "env_provider") unsetenv("PEEKABOO_AI_PROVIDERS") // After clearing env override, manager should return to baseline let restoredProviders = manager.getAIProviders(cliValue: nil) #expect(restoredProviders == baselineProviders) } @Test("Get OpenAI API key with configuration", .tags(.fast)) func getOpenAIAPIKeyWithConfig() { let manager = ConfigurationManager.shared // Capture baseline (may come from credentials) let baselineKey = manager.getOpenAIAPIKey() setenv("OPENAI_API_KEY", "test_api_key", 1) let envKey = manager.getOpenAIAPIKey() #expect(envKey == "test_api_key") // Restore environment if let baselineKey { setenv("OPENAI_API_KEY", baselineKey, 1) } else { unsetenv("OPENAI_API_KEY") } let restoredKey = manager.getOpenAIAPIKey() #expect(restoredKey == baselineKey) } @Test("Get Ollama base URL with configuration", .tags(.fast)) func getOllamaBaseURLWithConfig() { let manager = ConfigurationManager.shared // Test default value let defaultURL = manager.getOllamaBaseURL() #expect(defaultURL == "http://localhost:11434") // Test with environment variable setenv("PEEKABOO_OLLAMA_BASE_URL", "http://custom:11434", 1) let envURL = manager.getOllamaBaseURL() #expect(envURL == "http://custom:11434") unsetenv("PEEKABOO_OLLAMA_BASE_URL") } } extension ConfigurationTests { fileprivate static func decodedDictionary(from data: Data) throws -> [String: Any] { let json = try JSONSerialization.jsonObject(with: data) guard let dictionary = json as? [String: Any] else { throw ConfigurationTestsError.invalidJSON } return dictionary } } private enum ConfigurationTestsError: Error { case invalidJSON }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/steipete/Peekaboo'

If you have feedback or need assistance with the MCP directory API, please join our Discord server