mirror of
https://github.com/saymrwulf/alpha-arena.git
synced 2026-07-28 19:51:02 +00:00
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
181 lines
6 KiB
Swift
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
|
|
}
|
|
}
|