XCode-Claude-Workflow/SoliCardsTests/Models/DifficultyTests.swift
idev2025 0f989f5c86 feat: SoliCards v1.2.0 — native SwiftUI solitaire for iOS, iPadOS, macOS
Complete native rewrite of the web-based SoliCards game as a SwiftUI
multiplatform app targeting iOS 17+, iPadOS 17+, and macOS 14+.

Three solitaire variants (Klondike, Spider, FreeCell) with full game
rules, drag & drop, smart zoom layout, 6 themes, 4 difficulty levels,
SwiftData persistence, VoiceOver accessibility, and 57 unit tests.

Key features:
- MVVM + Protocol-Oriented Strategy architecture
- DragGesture with coordinate-space hit-testing (long press + drag)
- Smart zoom: cards auto-size to fit screen based on deepest column
- Landscape: 30% bigger cards with scrollable overflow (iOS)
- macOS: 120pt card cap, 92% height buffer for window resizing
- Auto-save, game resume, statistics tracking via SwiftData
- Privacy manifest, app icon, String Catalog, zero dependencies

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 07:33:52 -04:00

134 lines
3.5 KiB
Swift

import Testing
@testable import SoliCards
@Suite("Difficulty Tests")
struct DifficultyTests {
@Test("Easy settings")
func easySettings() {
let settings = Difficulty.easy.settings
#expect(settings.drawCount == 1)
#expect(settings.maxUndos == .max)
#expect(settings.hintsEnabled)
#expect(settings.scoreMultiplier == 0.5)
}
@Test("Medium settings")
func mediumSettings() {
let settings = Difficulty.medium.settings
#expect(settings.drawCount == 3)
#expect(settings.maxUndos == 20)
#expect(settings.hintsEnabled)
}
@Test("Hard settings disable hints")
func hardNoHints() {
let settings = Difficulty.hard.settings
#expect(!settings.hintsEnabled)
#expect(settings.maxUndos == 10)
}
@Test("Expert settings are most restrictive")
func expertSettings() {
let settings = Difficulty.expert.settings
#expect(!settings.hintsEnabled)
#expect(settings.maxUndos == 5)
#expect(settings.scoreMultiplier == 2.0)
}
@Test("All difficulties have display names")
func displayNames() {
for difficulty in Difficulty.allCases {
#expect(!difficulty.displayName.isEmpty)
}
}
}
@Suite("GameVariant Tests")
struct GameVariantTests {
@Test("Klondike properties")
func klondikeProps() {
let v = GameVariant.klondike
#expect(v.tableauCount == 7)
#expect(v.foundationCount == 4)
#expect(v.deckCount == 1)
#expect(v.hasWaste)
#expect(v.hasStock)
#expect(!v.hasFreeCells)
}
@Test("Spider properties")
func spiderProps() {
let v = GameVariant.spider
#expect(v.tableauCount == 10)
#expect(v.foundationCount == 8)
#expect(v.deckCount == 2)
#expect(!v.hasFreeCells)
}
@Test("FreeCell properties")
func freeCellProps() {
let v = GameVariant.freeCell
#expect(v.tableauCount == 8)
#expect(v.foundationCount == 4)
#expect(v.deckCount == 1)
#expect(!v.hasWaste)
#expect(!v.hasStock)
#expect(v.hasFreeCells)
#expect(v.freeCellCount == 4)
}
}
@Suite("Rank Tests")
struct RankTests {
@Test("Rank ordering")
func rankOrder() {
#expect(Rank.ace < Rank.two)
#expect(Rank.queen < Rank.king)
#expect(Rank.ace.rawValue == 1)
#expect(Rank.king.rawValue == 13)
}
@Test("All 13 ranks exist")
func allRanks() {
#expect(Rank.allCases.count == 13)
}
@Test("File names for assets")
func fileNames() {
#expect(Rank.ace.fileName == "ace")
#expect(Rank.two.fileName == "2")
#expect(Rank.ten.fileName == "10")
#expect(Rank.jack.fileName == "jack")
#expect(Rank.queen.fileName == "queen")
#expect(Rank.king.fileName == "king")
}
}
@Suite("Suit Tests")
struct SuitTests {
@Test("Red and black suits")
func suitColors() {
#expect(Suit.hearts.color == .red)
#expect(Suit.diamonds.color == .red)
#expect(Suit.spades.color == .black)
#expect(Suit.clubs.color == .black)
}
@Test("All 4 suits exist")
func allSuits() {
#expect(Suit.allCases.count == 4)
}
@Test("Suit symbols")
func symbols() {
#expect(Suit.spades.symbol == "")
#expect(Suit.hearts.symbol == "")
#expect(Suit.diamonds.symbol == "")
#expect(Suit.clubs.symbol == "")
}
}