You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

205 lines
8.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import XCTest
@testable import DropTwoCore
final class FileNameParserTests: XCTestCase {
// MARK: - Erfolgreiches Parsen
func testParsesStandardFileName() {
let result = FileNameParser.parse("SOMOS-9x16-v3-DE.mp4")
guard case .parsed(let parsed) = result.outcome else {
return XCTFail("Erwartete .parsed, bekam \(result.outcome)")
}
XCTAssertEqual(parsed.projectName, "SOMOS")
XCTAssertEqual(parsed.sourceFormatToken, "9x16")
XCTAssertEqual(parsed.remainder, "v3-DE")
XCTAssertEqual(parsed.fileExtension, "mp4")
XCTAssertEqual(parsed.originalFileName, "SOMOS-9x16-v3-DE.mp4")
XCTAssertEqual(parsed.targetFileName, "SOMOS-4x5-v3-DE.mp4")
}
func testProjectNameWithHyphenIsPreserved() {
let result = FileNameParser.parse("Somos-Pendant-9x16-v3-DE.mp4")
guard case .parsed(let parsed) = result.outcome else {
return XCTFail("Erwartete .parsed, bekam \(result.outcome)")
}
XCTAssertEqual(parsed.projectName, "Somos-Pendant")
XCTAssertEqual(parsed.targetFileName, "Somos-Pendant-4x5-v3-DE.mp4")
}
func testLanguageSegmentWithHyphenIsPreserved() {
let result = FileNameParser.parse("SOMOS-9x16-v3-EN-US.mp4")
guard case .parsed(let parsed) = result.outcome else {
return XCTFail("Erwartete .parsed, bekam \(result.outcome)")
}
XCTAssertEqual(parsed.projectName, "SOMOS")
XCTAssertEqual(parsed.remainder, "v3-EN-US")
XCTAssertEqual(parsed.targetFileName, "SOMOS-4x5-v3-EN-US.mp4")
}
func testCaseInsensitiveFormatTokenIsRecognized() {
let result = FileNameParser.parse("somos-9X16-v3-de.mp4")
guard case .parsed(let parsed) = result.outcome else {
return XCTFail("Erwartete .parsed, bekam \(result.outcome)")
}
// Sonst unveränderte Schreibweise bleibt erhalten.
XCTAssertEqual(parsed.projectName, "somos")
XCTAssertEqual(parsed.sourceFormatToken, "9X16")
XCTAssertEqual(parsed.remainder, "v3-de")
XCTAssertEqual(parsed.targetFileName, "somos-4x5-v3-de.mp4")
}
func testFileExtensionIsPreservedVerbatim() {
for ext in ["mp4", "mov", "mxf", "MOV"] {
let fileName = "SOMOS-9x16-v3-DE.\(ext)"
let result = FileNameParser.parse(fileName)
guard case .parsed(let parsed) = result.outcome else {
return XCTFail("Erwartete .parsed für \(fileName), bekam \(result.outcome)")
}
XCTAssertEqual(parsed.fileExtension, ext)
XCTAssertEqual(parsed.targetFileName, "SOMOS-4x5-v3-DE.\(ext)")
}
}
// MARK: - Skip
func testAlreadyTargetFormatIsSkipped() {
let result = FileNameParser.parse("SOMOS-4x5-v3-DE.mp4")
XCTAssertEqual(result.outcome, .skipped(.alreadyTargetFormat))
}
// MARK: - Rejection
func testMissingFormatSegmentIsRejected() {
let result = FileNameParser.parse("SOMOS-v3-DE.mp4")
XCTAssertEqual(result.outcome, .rejected(.formatSegmentMissing))
}
func testFinderDuplicateIsRejected() {
let result = FileNameParser.parse("SOMOS-9x16-v3-DE (1).mp4")
XCTAssertEqual(result.outcome, .rejected(.finderDuplicate))
}
func testFinderDuplicateTakesPriorityOverMissingFormatSegment() {
// Beide Aussagen wären technisch wahr; die handlungsleitende
// Meldung (falsche Kopie erwischt) muss gewinnen.
let result = FileNameParser.parse("SOMOS-v3-DE (1).mp4")
XCTAssertEqual(result.outcome, .rejected(.finderDuplicate))
}
// MARK: - a) Rechtestes Vorkommen gewinnt
func testRightmostFormatOccurrenceWins() {
let result = FileNameParser.parse("Kampagne-9x16-Teaser-9x16-v3-DE.mp4")
guard case .parsed(let parsed) = result.outcome else {
return XCTFail("Erwartete .parsed, bekam \(result.outcome)")
}
XCTAssertEqual(parsed.projectName, "Kampagne-9x16-Teaser")
XCTAssertEqual(parsed.remainder, "v3-DE")
XCTAssertEqual(parsed.targetFileName, "Kampagne-9x16-Teaser-4x5-v3-DE.mp4")
}
func testRightmostAlreadyTargetFormatOccurrenceWins() {
let result = FileNameParser.parse("Kampagne-4x5-Teaser-4x5-v3-DE.mp4")
XCTAssertEqual(result.outcome, .skipped(.alreadyTargetFormat))
}
// MARK: - b) Projekt und Rest müssen existieren
func testRejectsWhenNoProjectSegment() {
let result = FileNameParser.parse("9x16-v3-DE.mp4")
XCTAssertEqual(result.outcome, .rejected(.formatSegmentMissing))
}
func testParsesWithoutRemainderSegment() {
let result = FileNameParser.parse("SOMOS-9x16.mp4")
guard case .parsed(let parsed) = result.outcome else {
return XCTFail("Erwartete .parsed, bekam \(result.outcome)")
}
XCTAssertEqual(parsed.projectName, "SOMOS")
XCTAssertEqual(parsed.remainder, "")
XCTAssertEqual(parsed.targetFileName, "SOMOS-4x5.mp4")
}
// MARK: - d) Lockere Schreibweisen
func testUnderscoreAndSpaceSeparatorsArePreserved() {
let cases = [
("SOMOS_9x16_v3_DE.mp4", "SOMOS", "v3_DE", "SOMOS_4x5_v3_DE.mp4"),
("SOMOS 9x16 v3 DE.mov", "SOMOS", "v3 DE", "SOMOS 4x5 v3 DE.mov"),
("Somos Pendant - 9X16_v3-DE.mp4", "Somos Pendant", "v3-DE", "Somos Pendant - 4x5_v3-DE.mp4"),
("SOMOS-9×16-v3.mp4", "SOMOS", "v3", "SOMOS-4x5-v3.mp4"),
("SOMOS (9 x 16) v3.mp4", "SOMOS", "v3", "SOMOS (4x5) v3.mp4")
]
for (fileName, project, remainder, target) in cases {
guard case .parsed(let parsed) = FileNameParser.parse(fileName).outcome else {
XCTFail("Erwartete .parsed für \(fileName)")
continue
}
XCTAssertEqual(parsed.projectName, project, fileName)
XCTAssertEqual(parsed.remainder, remainder, fileName)
XCTAssertEqual(parsed.targetFileName, target, fileName)
}
}
func testTokenInsideWordIsNotAFormat() {
XCTAssertEqual(FileNameParser.parse("SOMOS-19x160-v3.mp4").outcome, .rejected(.formatSegmentMissing))
XCTAssertEqual(FileNameParser.parse("SOMOSx9x16v3.mp4").outcome, .rejected(.formatSegmentMissing))
}
func testTargetFormatInAnySpellingIsSkipped() {
for fileName in ["SOMOS_4X5_v3.mp4", "SOMOS 4x5.mp4", "SOMOS-4×5-v3-DE.mp4"] {
XCTAssertEqual(FileNameParser.parse(fileName).outcome, .skipped(.alreadyTargetFormat), fileName)
}
}
// MARK: - e) Format anhängen, wenn es fehlt
func testAppendingFormatUsesWholeStemAsProject() {
let parsed = FileNameParser.appendingTargetFormat(to: "Sommerfest Teaser.mov")
XCTAssertEqual(parsed?.projectName, "Sommerfest Teaser")
XCTAssertEqual(parsed?.targetFileName, "Sommerfest Teaser 4x5.mov")
XCTAssertEqual(parsed?.originalFileName, "Sommerfest Teaser.mov")
}
func testAppendingFormatPicksSeparatorFromName() {
XCTAssertEqual(FileNameParser.appendingTargetFormat(to: "SOMOS-v3-DE.mp4")?.targetFileName, "SOMOS-v3-DE-4x5.mp4")
XCTAssertEqual(FileNameParser.appendingTargetFormat(to: "SOMOS_v3.mp4")?.targetFileName, "SOMOS_v3_4x5.mp4")
XCTAssertEqual(FileNameParser.appendingTargetFormat(to: "SOMOS.mp4")?.targetFileName, "SOMOS-4x5.mp4")
}
func testAppendingFormatOnlyForMissingFormat() {
XCTAssertNil(FileNameParser.appendingTargetFormat(to: "SOMOS-9x16-v3-DE.mp4"))
XCTAssertNil(FileNameParser.appendingTargetFormat(to: "SOMOS-4x5-v3-DE.mp4"))
XCTAssertNil(FileNameParser.appendingTargetFormat(to: "SOMOS-v3-DE (1).mp4"))
}
// MARK: - c) Format-Segment in der Ausgabe immer klein geschrieben
func testTargetFormatTokenIsAlwaysLowercase() {
let result = FileNameParser.parse("SOMOS-9X16-v3-DE.mp4")
guard case .parsed(let parsed) = result.outcome else {
return XCTFail("Erwartete .parsed, bekam \(result.outcome)")
}
XCTAssertEqual(parsed.sourceFormatToken, "9X16")
XCTAssertTrue(parsed.targetFileName.contains("-4x5-"))
XCTAssertFalse(parsed.targetFileName.contains("4X16"))
XCTAssertEqual(parsed.targetFileName, "SOMOS-4x5-v3-DE.mp4")
}
}

Powered by TurnKey Linux.