169 lines
4.2 KiB
Swift
169 lines
4.2 KiB
Swift
import Testing
|
||
import SwiftUI
|
||
@testable import bookstax
|
||
|
||
// MARK: - Color Hex Parsing
|
||
|
||
@Suite("Color – Hex Parsing")
|
||
struct ColorHexParsingTests {
|
||
|
||
// MARK: Valid 6-digit hex
|
||
|
||
@Test("6-digit hex without # prefix parses successfully")
|
||
func sixDigitNoPound() {
|
||
#expect(Color(hex: "FF0000") != nil)
|
||
}
|
||
|
||
@Test("6-digit hex with # prefix parses successfully")
|
||
func sixDigitWithPound() {
|
||
#expect(Color(hex: "#FF0000") != nil)
|
||
}
|
||
|
||
@Test("Black hex #000000 parses successfully")
|
||
func blackHex() {
|
||
#expect(Color(hex: "#000000") != nil)
|
||
}
|
||
|
||
@Test("White hex #FFFFFF parses successfully")
|
||
func whiteHex() {
|
||
#expect(Color(hex: "#FFFFFF") != nil)
|
||
}
|
||
|
||
@Test("Lowercase hex parses successfully")
|
||
func lowercaseHex() {
|
||
#expect(Color(hex: "#ff6600") != nil)
|
||
}
|
||
|
||
// MARK: Valid 3-digit hex
|
||
|
||
@Test("3-digit hex #FFF is valid shorthand")
|
||
func threeDigitFFF() {
|
||
#expect(Color(hex: "#FFF") != nil)
|
||
}
|
||
|
||
@Test("3-digit hex #000 is valid shorthand")
|
||
func threeDigitZero() {
|
||
#expect(Color(hex: "#000") != nil)
|
||
}
|
||
|
||
@Test("3-digit hex #F60 is expanded to #FF6600")
|
||
func threeDigitExpansion() {
|
||
let threeDigit = Color(hex: "#F60")
|
||
let sixDigit = Color(hex: "#FF6600")
|
||
// Both should parse successfully
|
||
#expect(threeDigit != nil)
|
||
#expect(sixDigit != nil)
|
||
}
|
||
|
||
// MARK: Invalid inputs
|
||
|
||
@Test("5-digit hex returns nil")
|
||
func fiveDigitInvalid() {
|
||
#expect(Color(hex: "#FFFFF") == nil)
|
||
}
|
||
|
||
@Test("7-digit hex returns nil")
|
||
func sevenDigitInvalid() {
|
||
#expect(Color(hex: "#FFFFFFF") == nil)
|
||
}
|
||
|
||
@Test("Empty string returns nil")
|
||
func emptyStringInvalid() {
|
||
#expect(Color(hex: "") == nil)
|
||
}
|
||
|
||
@Test("Non-hex characters return nil")
|
||
func nonHexCharacters() {
|
||
#expect(Color(hex: "#GGGGGG") == nil)
|
||
}
|
||
|
||
@Test("Just # returns nil")
|
||
func onlyHash() {
|
||
#expect(Color(hex: "#") == nil)
|
||
}
|
||
}
|
||
|
||
// MARK: - Color Hex Round-trip
|
||
|
||
@Suite("Color – Hex Round-trip")
|
||
struct ColorHexRoundTripTests {
|
||
|
||
@Test("Red #FF0000 round-trips correctly")
|
||
func redRoundTrip() {
|
||
let color = Color(hex: "#FF0000")!
|
||
let hex = color.toHexString()
|
||
#expect(hex == "#FF0000")
|
||
}
|
||
|
||
@Test("Green #00FF00 round-trips correctly")
|
||
func greenRoundTrip() {
|
||
let color = Color(hex: "#00FF00")!
|
||
let hex = color.toHexString()
|
||
#expect(hex == "#00FF00")
|
||
}
|
||
|
||
@Test("Blue #0000FF round-trips correctly")
|
||
func blueRoundTrip() {
|
||
let color = Color(hex: "#0000FF")!
|
||
let hex = color.toHexString()
|
||
#expect(hex == "#0000FF")
|
||
}
|
||
|
||
@Test("Custom color #3A7B55 round-trips correctly")
|
||
func customColorRoundTrip() {
|
||
let color = Color(hex: "#3A7B55")!
|
||
let hex = color.toHexString()
|
||
#expect(hex == "#3A7B55")
|
||
}
|
||
}
|
||
|
||
// MARK: - AccentTheme
|
||
|
||
@Suite("AccentTheme – Properties")
|
||
struct AccentThemeTests {
|
||
|
||
@Test("All cases are represented in CaseIterable")
|
||
func allCasesPresent() {
|
||
#expect(AccentTheme.allCases.count == 8)
|
||
}
|
||
|
||
@Test("id equals rawValue")
|
||
func idEqualsRawValue() {
|
||
for theme in AccentTheme.allCases {
|
||
#expect(theme.id == theme.rawValue)
|
||
}
|
||
}
|
||
|
||
@Test("Every theme has a non-empty displayName")
|
||
func displayNamesNonEmpty() {
|
||
for theme in AccentTheme.allCases {
|
||
#expect(!theme.displayName.isEmpty)
|
||
}
|
||
}
|
||
|
||
@Test("accentColor equals shelfColor")
|
||
func accentColorEqualsShelfColor() {
|
||
for theme in AccentTheme.allCases {
|
||
#expect(theme.accentColor == theme.shelfColor)
|
||
}
|
||
}
|
||
|
||
@Test("Ocean theme has expected displayName")
|
||
func oceanDisplayName() {
|
||
#expect(AccentTheme.ocean.displayName == "Ocean")
|
||
}
|
||
|
||
@Test("Graphite theme has expected displayName")
|
||
func graphiteDisplayName() {
|
||
#expect(AccentTheme.graphite.displayName == "Graphite")
|
||
}
|
||
|
||
@Test("All themes can be init'd from rawValue")
|
||
func initFromRawValue() {
|
||
for theme in AccentTheme.allCases {
|
||
let reinit = AccentTheme(rawValue: theme.rawValue)
|
||
#expect(reinit == theme)
|
||
}
|
||
}
|
||
}
|