Files
links/mobile/template_test.swift
T
2025-08-16 18:06:07 +10:00

124 lines
4.3 KiB
Swift

#!/usr/bin/env swift
import Foundation
// Copy the URLTemplateProcessor code for testing
struct URLTemplateProcessor {
static func processTemplate(_ template: String, with parameters: [String: String]) -> String {
var processedURL = template
let extractedParams = extractParameters(from: template)
for param in extractedParams {
let placeholder = "{\(param.name)" + (param.defaultValue != nil ? ",default=\(param.defaultValue!)" : "") + "}"
let value = parameters[param.name] ?? param.defaultValue ?? ""
processedURL = processedURL.replacingOccurrences(of: placeholder, with: value)
}
return processedURL
}
static func extractParameters(from template: String) -> [TemplateParameter] {
var parameters: [TemplateParameter] = []
// Updated pattern to handle optional spaces around comma and default=
let pattern = "\\{([^,}]+)(?:\\s*,\\s*default\\s*=\\s*([^}]+))?\\}"
guard let regex = try? NSRegularExpression(pattern: pattern, options: []) else {
return parameters
}
let matches = regex.matches(in: template, options: [], range: NSRange(location: 0, length: template.utf16.count))
for match in matches {
let nameRange = match.range(at: 1)
let defaultRange = match.range(at: 2)
if let nameSwiftRange = Range(nameRange, in: template) {
let name = String(template[nameSwiftRange]).trimmingCharacters(in: .whitespaces)
var defaultValue: String? = nil
if defaultRange.location != NSNotFound,
let defaultSwiftRange = Range(defaultRange, in: template) {
defaultValue = String(template[defaultSwiftRange]).trimmingCharacters(in: .whitespaces)
}
parameters.append(TemplateParameter(name: name, defaultValue: defaultValue))
}
}
return parameters
}
static func validateTemplate(_ template: String) -> Bool {
let extractedParams = extractParameters(from: template)
// Check if all placeholders are valid
let pattern = "\\{[^{}]*\\}"
guard let regex = try? NSRegularExpression(pattern: pattern, options: []) else {
return false
}
let matches = regex.matches(in: template, options: [], range: NSRange(location: 0, length: template.utf16.count))
// Each match should correspond to a valid parameter
for match in matches {
if let matchRange = Range(match.range, in: template) {
let matchString = String(template[matchRange])
let isValid = extractedParams.contains { param in
matchString.contains(param.name)
}
if !isValid {
return false
}
}
}
return true
}
static func hasParameters(_ template: String) -> Bool {
return template.contains("{") && template.contains("}")
}
}
struct TemplateParameter {
let name: String
let defaultValue: String?
var isRequired: Bool {
return defaultValue == nil
}
}
// Test cases
print("Testing URLTemplateProcessor...")
let testCases = [
"https://google.com/search?q={query, default=hello}",
"https://google.com/search?q={query}",
"https://github.com/{user}/{repo}",
"https://youtube.com/watch?v={videoId}",
"https://maps.apple.com/?q={location,default=New York}",
"https://example.com/{invalid syntax}",
"https://example.com/no-parameters",
"https://example.com/{query,default=test}/{page,default=1}"
]
for testCase in testCases {
let isValid = URLTemplateProcessor.validateTemplate(testCase)
let hasParams = URLTemplateProcessor.hasParameters(testCase)
let parameters = URLTemplateProcessor.extractParameters(from: testCase)
print("\nTest: \(testCase)")
print(" Valid: \(isValid)")
print(" Has Parameters: \(hasParams)")
print(" Parameters: \(parameters.map { "\($0.name)" + (($0.defaultValue != nil) ? ",default=\($0.defaultValue!)" : "") })")
if isValid && hasParams {
print(" ✅ Would show blue border")
} else if !hasParams {
print(" ⚠️ Would show warning (no parameters)")
} else {
print(" ❌ Would show error (invalid)")
}
}