alpha-arena/macos-app/AlphaArenaTests/ViewTests.swift
oho 774f8b3f61 Initial commit: Alpha Arena - Polymarket Autonomous Trading Harness
A comprehensive autonomous trading system for Polymarket prediction markets
featuring multi-LLM provider support, a native macOS menu bar app, and a
web-based control dashboard.

Key features:
- Multi-agent trading system (Research, Risk, Execution, Reflection agents)
- LLM provider flexibility (Anthropic, OpenAI, Google, xAI, Local models)
- Automatic provider fallback chain for resilience
- Native Swift/SwiftUI macOS menu bar application
- FastAPI web dashboard with real-time WebSocket updates
- Risk management with kill switch
- Technical indicators and market analysis
2026-01-12 23:04:58 +01:00

181 lines
6 KiB
Swift

import XCTest
import SwiftUI
@testable import AlphaArena
/// Tests for SwiftUI views
final class ViewTests: XCTestCase {
// MARK: - StatusItemView Tests
func testStatusItemViewIcons() {
// Test different server states produce different icons
let runningIcon = StatusItemView.iconForState(.running, tradingActive: true)
let stoppedIcon = StatusItemView.iconForState(.stopped, tradingActive: false)
let errorIcon = StatusItemView.iconForState(.error, tradingActive: false)
let startingIcon = StatusItemView.iconForState(.starting, tradingActive: false)
// Icons should be different for different states
XCTAssertNotEqual(runningIcon, stoppedIcon)
XCTAssertNotEqual(runningIcon, errorIcon)
XCTAssertNotEqual(stoppedIcon, errorIcon)
// Starting should show a loading-type icon
XCTAssertNotEqual(startingIcon, runningIcon)
}
func testStatusItemViewTradingActiveIcon() {
// Trading active vs inactive should have different icons when server is running
let tradingActiveIcon = StatusItemView.iconForState(.running, tradingActive: true)
let tradingInactiveIcon = StatusItemView.iconForState(.running, tradingActive: false)
// These should be different to indicate trading state
XCTAssertNotEqual(tradingActiveIcon, tradingInactiveIcon)
}
// MARK: - DashboardView Formatting Tests
func testPnLFormatting() {
// Test positive P&L
let positivePnL = DashboardView.formatPnL(127.45)
XCTAssertTrue(positivePnL.contains("127.45"))
XCTAssertTrue(positivePnL.hasPrefix("+"))
// Test negative P&L
let negativePnL = DashboardView.formatPnL(-45.67)
XCTAssertTrue(negativePnL.contains("45.67"))
XCTAssertTrue(negativePnL.hasPrefix("-"))
// Test zero P&L
let zeroPnL = DashboardView.formatPnL(0.0)
XCTAssertTrue(zeroPnL.contains("0.00"))
}
func testPositionCountFormatting() {
// Test singular
let singular = DashboardView.formatPositions(1)
XCTAssertTrue(singular.contains("1"))
// Test plural
let plural = DashboardView.formatPositions(5)
XCTAssertTrue(plural.contains("5"))
// Test zero
let zero = DashboardView.formatPositions(0)
XCTAssertTrue(zero.contains("0"))
}
// MARK: - MenuBarView State Tests
func testMenuItemsForServerStopped() {
// When server is stopped, Start should be enabled, Stop should be disabled
let state = ServerState(status: .stopped)
XCTAssertTrue(MenuBarView.isStartEnabled(for: state))
XCTAssertFalse(MenuBarView.isStopEnabled(for: state))
XCTAssertFalse(MenuBarView.isDashboardEnabled(for: state))
}
func testMenuItemsForServerRunning() {
// When server is running, Start should be disabled, Stop should be enabled
var state = ServerState()
state.status = .running
XCTAssertFalse(MenuBarView.isStartEnabled(for: state))
XCTAssertTrue(MenuBarView.isStopEnabled(for: state))
XCTAssertTrue(MenuBarView.isDashboardEnabled(for: state))
}
func testMenuItemsForServerStarting() {
// When server is starting, both should be disabled
var state = ServerState()
state.status = .starting
XCTAssertFalse(MenuBarView.isStartEnabled(for: state))
XCTAssertFalse(MenuBarView.isStopEnabled(for: state))
XCTAssertFalse(MenuBarView.isDashboardEnabled(for: state))
}
func testMenuItemsForServerError() {
// When server has error, Start should be enabled to retry
var state = ServerState()
state.status = .error
XCTAssertTrue(MenuBarView.isStartEnabled(for: state))
XCTAssertFalse(MenuBarView.isStopEnabled(for: state))
XCTAssertFalse(MenuBarView.isDashboardEnabled(for: state))
}
// MARK: - URL Construction Tests
func testServerURLConstruction() {
let settings = AppSettings.shared
let originalMode = settings.networkMode
let originalPort = settings.serverPort
defer {
settings.networkMode = originalMode
settings.serverPort = originalPort
}
// Test localhost mode
settings.networkMode = .localhost
settings.serverPort = 8000
XCTAssertEqual(settings.serverURL, "http://127.0.0.1:8000")
// Test LAN mode
settings.networkMode = .lan
settings.serverPort = 9000
XCTAssertEqual(settings.serverURL, "http://0.0.0.0:9000")
}
}
// MARK: - View Helper Extensions for Testing
extension StatusItemView {
/// Returns the icon name for a given server state
static func iconForState(_ status: ServerStatus, tradingActive: Bool) -> String {
switch status {
case .running:
return tradingActive ? "circle.fill" : "circle.lefthalf.filled"
case .stopped:
return "circle"
case .starting:
return "circle.dotted"
case .stopping:
return "circle.dotted"
case .error:
return "exclamationmark.circle.fill"
}
}
}
extension DashboardView {
/// Format P&L value for display
static func formatPnL(_ value: Double) -> String {
let sign = value >= 0 ? "+" : "-"
return "\(sign)$\(String(format: "%.2f", abs(value)))"
}
/// Format position count for display
static func formatPositions(_ count: Int) -> String {
return "\(count) \(count == 1 ? "position" : "positions")"
}
}
extension MenuBarView {
/// Check if Start menu item should be enabled
static func isStartEnabled(for state: ServerState) -> Bool {
return state.status == .stopped || state.status == .error
}
/// Check if Stop menu item should be enabled
static func isStopEnabled(for state: ServerState) -> Bool {
return state.status == .running
}
/// Check if Dashboard menu item should be enabled
static func isDashboardEnabled(for state: ServerState) -> Bool {
return state.status == .running
}
}