Renames Sources/PlumTV→TVAnarchy and PlumTVCore→TVAnarchyCore (the rename the auto-commit service couldn't stage — it git-add'd the old, now-gone paths and aborted every cycle), and commits the accumulated work: - Library: black-built index fast path (LibraryIndex + scanFromIndex) with NFS-walk fallback; incremental --add on download-complete; mtime staleness gate; loose-file series-collapse fix; determinate scan/index progress. - Cover art: keyless TVmaze cartoon-vs-live-action disambiguation (type/year). - Player: sleep timer (timed + end-of-episode); visibility-gated polling. - Home: Continue Watching cover art + live refresh; Recently Added; adult gate. - Logs: multi-line selection + copy; truncated giant tx-list errors. - Hover previews (opt-in) via black ffmpeg + scp. Also gitignores foreign project trees (governor/mcp/fleet/recommender) that sit in this directory but belong to their own repos. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
41 lines
1.8 KiB
Swift
41 lines
1.8 KiB
Swift
import XCTest
|
|
@testable import TVAnarchyCore
|
|
|
|
final class TrackPreferenceTests: XCTestCase {
|
|
func testDubSubLanguageMapping() {
|
|
XCTAssertEqual(DubSub.sub.audioLangs.first, "jpn")
|
|
XCTAssertTrue(DubSub.sub.subsEnabled)
|
|
XCTAssertEqual(DubSub.dub.audioLangs.first, "eng")
|
|
XCTAssertFalse(DubSub.dub.subsEnabled)
|
|
}
|
|
|
|
func testChoiceResolutionPrecedence() {
|
|
var p = TrackPreferences(globalDefault: .dub)
|
|
// anime with no override → sub (the default we want)
|
|
XCTAssertEqual(p.choice(series: "Frieren", category: "anime"), .sub)
|
|
// non-anime, no override → global default (dub: native audio, no forced subs)
|
|
XCTAssertEqual(p.choice(series: "Psych", category: "tv"), .dub)
|
|
// explicit per-series override beats both
|
|
p.setSeries("Frieren", .dub)
|
|
XCTAssertEqual(p.choice(series: "Frieren", category: "anime"), .dub)
|
|
p.setSeries("Psych", .sub)
|
|
XCTAssertEqual(p.choice(series: "Psych", category: "tv"), .sub)
|
|
// key is normalized (case/space-insensitive)
|
|
XCTAssertEqual(p.choice(series: " frieren ", category: nil), .dub)
|
|
}
|
|
|
|
func testLangMatching() {
|
|
XCTAssertTrue(trackLangMatches("jpn", ["jpn", "ja"]))
|
|
XCTAssertTrue(trackLangMatches("ja", ["jpn", "ja", "jp"]))
|
|
XCTAssertTrue(trackLangMatches("eng", ["eng", "en"]))
|
|
XCTAssertFalse(trackLangMatches("ger", ["eng", "en"]))
|
|
XCTAssertFalse(trackLangMatches(nil, ["eng"]))
|
|
XCTAssertFalse(trackLangMatches("", ["eng"]))
|
|
}
|
|
|
|
func testTrackLabel() {
|
|
XCTAssertEqual(MediaTrack(id: 1, kind: .audio, lang: "jpn", title: "Stereo").label, "JPN · Stereo")
|
|
XCTAssertEqual(MediaTrack(id: 2, kind: .audio, codec: "ac3").label, "AC3")
|
|
XCTAssertEqual(MediaTrack(id: 3, kind: .subtitle).label, "Track 3")
|
|
}
|
|
}
|