Skip to content

Commit

Permalink
Migrated from XCTest unit tests to Swift Testing
Browse files Browse the repository at this point in the history
  • Loading branch information
orchetect committed Oct 26, 2024
1 parent e092b16 commit ae8a4ef
Show file tree
Hide file tree
Showing 12 changed files with 318 additions and 363 deletions.
95 changes: 48 additions & 47 deletions Tests/MarkersExtractorTests/AnnotationsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@
// Licensed under MIT License
//

@testable import MarkersExtractor
import OTCore
import TimecodeKitCore
import XCTest
import Testing
import TestingExtensions
@testable import MarkersExtractor

final class AnnotationsTests: XCTestCase {
@Suite struct AnnotationsTests {
// TODO: add test for filtering disabled captions once that's implemented
/// Test importing captions
func testAnnotations_CaptionsOnly() async throws {
@Test func annotations_CaptionsOnly() async throws {
var settings = try MarkersExtractor.Settings(
fcpxml: FCPXMLFile(fileContents: fcpxmlTestData),
outputDir: FileManager.default.temporaryDirectory
Expand All @@ -27,31 +28,31 @@ final class AnnotationsTests: XCTestCase {

let markers = try await extractor.extractMarkers().markers

XCTAssertEqual(markers.count, 2)
#expect(markers.count == 2)

let fr: TimecodeFrameRate = .fps25

let marker0 = try XCTUnwrap(markers[safe: 0])
XCTAssertEqual(marker0.type, .caption)
XCTAssertEqual(marker0.name, "caption1")
XCTAssertEqual(marker0.notes, "")
XCTAssertEqual(marker0.roles.audio?.map(\.rawValue), ["Dialogue"]) // inherited from clip it's anchored on (TODO: ?)
XCTAssertEqual(marker0.roles.video?.rawValue, nil)
XCTAssertEqual(marker0.roles.caption?.rawValue, "iTT?captionFormat=ITT.en")
XCTAssertEqual(marker0.position, tc("01:00:03:00", at: fr))
let marker0 = try #require(markers[safe: 0])
#expect(marker0.type == .caption)
#expect(marker0.name == "caption1")
#expect(marker0.notes == "")
#expect(marker0.roles.audio?.map(\.rawValue) == ["Dialogue"]) // inherited from clip it's anchored on (TODO: ?)
#expect(marker0.roles.video?.rawValue == nil)
#expect(marker0.roles.caption?.rawValue == "iTT?captionFormat=ITT.en")
#expect(marker0.position == tc("01:00:03:00", at: fr))

let marker1 = try XCTUnwrap(markers[safe: 1])
XCTAssertEqual(marker1.type, .caption)
XCTAssertEqual(marker1.name, "caption2")
XCTAssertEqual(marker1.notes, "")
XCTAssertEqual(marker1.roles.audio?.map(\.rawValue), ["Dialogue"]) // inherited from clip it's anchored on (TODO: ?)
XCTAssertEqual(marker1.roles.video?.rawValue, nil)
XCTAssertEqual(marker1.roles.caption?.rawValue, "iTT?captionFormat=ITT.en")
XCTAssertEqual(marker1.position, tc("01:00:09:10", at: fr))
let marker1 = try #require(markers[safe: 1])
#expect(marker1.type == .caption)
#expect(marker1.name == "caption2")
#expect(marker1.notes == "")
#expect(marker1.roles.audio?.map(\.rawValue) == ["Dialogue"]) // inherited from clip it's anchored on (TODO: ?)
#expect(marker1.roles.video?.rawValue == nil)
#expect(marker1.roles.caption?.rawValue == "iTT?captionFormat=ITT.en")
#expect(marker1.position == tc("01:00:09:10", at: fr))
}

/// Test importing captions
func testAnnotations_MarkersAndCaptions() async throws {
@Test func annotations_MarkersAndCaptions() async throws {
var settings = try MarkersExtractor.Settings(
fcpxml: FCPXMLFile(fileContents: fcpxmlTestData),
outputDir: FileManager.default.temporaryDirectory
Expand All @@ -66,36 +67,36 @@ final class AnnotationsTests: XCTestCase {

let markers = try await extractor.extractMarkers().markers

XCTAssertEqual(markers.count, 3)
#expect(markers.count == 3)

let fr: TimecodeFrameRate = .fps25

let marker0 = try XCTUnwrap(markers[safe: 0])
XCTAssertEqual(marker0.type, .caption)
XCTAssertEqual(marker0.name, "caption1")
XCTAssertEqual(marker0.notes, "")
XCTAssertEqual(marker0.roles.audio?.map(\.rawValue), ["Dialogue"]) // inherited from clip it's anchored on (TODO: ?)
XCTAssertEqual(marker0.roles.video?.rawValue, nil)
XCTAssertEqual(marker0.roles.caption?.rawValue, "iTT?captionFormat=ITT.en")
XCTAssertEqual(marker0.position, tc("01:00:03:00", at: fr))
let marker0 = try #require(markers[safe: 0])
#expect(marker0.type == .caption)
#expect(marker0.name == "caption1")
#expect(marker0.notes == "")
#expect(marker0.roles.audio?.map(\.rawValue) == ["Dialogue"]) // inherited from clip it's anchored on (TODO: ?)
#expect(marker0.roles.video?.rawValue == nil)
#expect(marker0.roles.caption?.rawValue == "iTT?captionFormat=ITT.en")
#expect(marker0.position == tc("01:00:03:00", at: fr))

let marker1 = try XCTUnwrap(markers[safe: 1])
XCTAssertEqual(marker1.type, .caption)
XCTAssertEqual(marker1.name, "caption2")
XCTAssertEqual(marker1.notes, "")
XCTAssertEqual(marker1.roles.audio?.map(\.rawValue), ["Dialogue"]) // inherited from clip it's anchored on (TODO: ?)
XCTAssertEqual(marker1.roles.video?.rawValue, nil)
XCTAssertEqual(marker1.roles.caption?.rawValue, "iTT?captionFormat=ITT.en")
XCTAssertEqual(marker1.position, tc("01:00:09:10", at: fr))
let marker1 = try #require(markers[safe: 1])
#expect(marker1.type == .caption)
#expect(marker1.name == "caption2")
#expect(marker1.notes == "")
#expect(marker1.roles.audio?.map(\.rawValue) == ["Dialogue"]) // inherited from clip it's anchored on (TODO: ?)
#expect(marker1.roles.video?.rawValue == nil)
#expect(marker1.roles.caption?.rawValue == "iTT?captionFormat=ITT.en")
#expect(marker1.position == tc("01:00:09:10", at: fr))

let marker2 = try XCTUnwrap(markers[safe: 2])
XCTAssertEqual(marker2.type, .marker(.standard))
XCTAssertEqual(marker2.name, "marker1")
XCTAssertEqual(marker2.notes, "m1 notes")
XCTAssertEqual(marker2.roles.audio?.map(\.rawValue), ["Dialogue"]) // inherited from clip it's anchored on (TODO: ?)
XCTAssertEqual(marker2.roles.video?.rawValue, nil)
XCTAssertEqual(marker2.roles.caption?.rawValue, nil)
XCTAssertEqual(marker2.position, tc("01:00:27:10", at: fr))
let marker2 = try #require(markers[safe: 2])
#expect(marker2.type == .marker(.standard))
#expect(marker2.name == "marker1")
#expect(marker2.notes == "m1 notes")
#expect(marker2.roles.audio?.map(\.rawValue) == ["Dialogue"]) // inherited from clip it's anchored on (TODO: ?)
#expect(marker2.roles.video?.rawValue == nil)
#expect(marker2.roles.caption?.rawValue == nil)
#expect(marker2.position == tc("01:00:27:10", at: fr))
}
}

Expand Down
49 changes: 25 additions & 24 deletions Tests/MarkersExtractorTests/AudioOnlyTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
// Licensed under MIT License
//

@testable import MarkersExtractor
import DAWFileKit
import OTCore
import Testing
import TestingExtensions
import TimecodeKitCore
import XCTest
import DAWFileKit
@testable import MarkersExtractor

final class AudioOnlyTests: XCTestCase {
func testAudioOnly() async throws {
@Suite struct AudioOnlyTests {
@Test func audioOnly() async throws {
let outputDir = FileManager.default
.temporaryDirectory
.appendingPathComponent(UUID().uuidString)
Expand All @@ -27,36 +28,36 @@ final class AudioOnlyTests: XCTestCase {

let markers = try await extractor.extractMarkers().markers

XCTAssertEqual(markers.count, 1)
#expect(markers.count == 1)

let fr: TimecodeFrameRate = .fps24

let marker0 = try XCTUnwrap(markers[safe: 0])
XCTAssertEqual(marker0.name, "Marker 1")
XCTAssertEqual(marker0.position, tc("00:00:02:00", at: fr))
let marker0 = try #require(markers[safe: 0])
#expect(marker0.name == "Marker 1")
#expect(marker0.position == tc("00:00:02:00", at: fr))

XCTAssertEqual(marker0.roles.audio, [FinalCutPro.FCPXML.AudioRole(role: "Dialogue")])
XCTAssertEqual(marker0.roles.isAudioDefault, false) // TODO: Dialogue isn't a builtin/default role??
XCTAssertEqual(marker0.roles.isAudioEmpty, false)
XCTAssertEqual(marker0.roles.isAudioDefined, true) // exists in the XML
#expect(marker0.roles.audio == [FinalCutPro.FCPXML.AudioRole(role: "Dialogue")])
#expect(marker0.roles.isAudioDefault == false) // TODO: Dialogue isn't a builtin/default role??
#expect(marker0.roles.isAudioEmpty == false)
#expect(marker0.roles.isAudioDefined == true) // exists in the XML

XCTAssertEqual(marker0.roles.video, nil)
XCTAssertEqual(marker0.roles.isVideoDefault, false)
XCTAssertEqual(marker0.roles.isVideoEmpty, true)
XCTAssertEqual(marker0.roles.isVideoDefined, false) // was default, not defined
#expect(marker0.roles.video == nil)
#expect(marker0.roles.isVideoDefault == false)
#expect(marker0.roles.isVideoEmpty == true)
#expect(marker0.roles.isVideoDefined == false) // was default, not defined

XCTAssertEqual(marker0.roles.caption, nil)
#expect(marker0.roles.caption == nil)
}

/// Ensure that a placeholder thumbnail image is used for an audio-only clip.
func testAudioOnly_WithMedia_PNG() async throws {
@Test func audioOnly_WithMedia_PNG() async throws {
let tempDir = FileManager.default
.temporaryDirectory
.appendingPathComponent(UUID().uuidString)

try FileManager.default.createDirectory(at: tempDir, withIntermediateDirectories: false)

let dummyMediaData = try XCTUnwrap(EmbeddedResource.empty_mov.data)
let dummyMediaData = try #require(EmbeddedResource.empty_mov.data)
let dummyMediaURL = tempDir.appendingPathComponent("AudioOnly.mov")
try dummyMediaData.write(to: dummyMediaURL)

Expand Down Expand Up @@ -86,18 +87,18 @@ final class AudioOnlyTests: XCTestCase {
exportFilenames.forEach { print(" - " + $0) }

// ensure that a placeholder thumbnail was used for the audio-only clip
XCTAssertTrue(exportFilenames.contains("marker-placeholder.png"))
#expect(exportFilenames.contains("marker-placeholder.png"))
}

/// Ensure that a placeholder thumbnail image is used for an audio-only clip.
func testAudioOnly_WithMedia_GIF() async throws {
@Test func audioOnly_WithMedia_GIF() async throws {
let tempDir = FileManager.default
.temporaryDirectory
.appendingPathComponent(UUID().uuidString)

try FileManager.default.createDirectory(at: tempDir, withIntermediateDirectories: false)

let dummyMediaData = try XCTUnwrap(EmbeddedResource.empty_mov.data)
let dummyMediaData = try #require(EmbeddedResource.empty_mov.data)
let dummyMediaURL = tempDir.appendingPathComponent("AudioOnly.mov")
try dummyMediaData.write(to: dummyMediaURL)

Expand Down Expand Up @@ -127,7 +128,7 @@ final class AudioOnlyTests: XCTestCase {
exportFilenames.forEach { print(" - " + $0) }

// ensure that a placeholder thumbnail was used for the audio-only clip
XCTAssertTrue(exportFilenames.contains("marker-placeholder.gif"))
#expect(exportFilenames.contains("marker-placeholder.gif"))
}
}

Expand Down
78 changes: 42 additions & 36 deletions Tests/MarkersExtractorTests/BasicMarkersEmptyIDTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,55 @@
// Licensed under MIT License
//

@testable import MarkersExtractor
import Foundation
import Testing
import TestingExtensions
import TimecodeKitCore
import XCTest
@testable import MarkersExtractor

final class BasicMarkersEmptyIDTests: XCTestCase {
/// Ensure that empty marker ID strings cause an error and abort the conversion process.
func testBasicMarkers_extractMarkers_nonEmptyMarkerIDs() async throws {
var settings = try MarkersExtractor.Settings(
@Suite struct BasicMarkersEmptyIDTests {
var settings: MarkersExtractor.Settings

init() throws {
settings = try MarkersExtractor.Settings(
fcpxml: FCPXMLFile(fileContents: fcpxmlTestData),
outputDir: FileManager.default.temporaryDirectory
)
}

/// Ensure that empty marker ID strings cause an error and abort the conversion process.
@Test(arguments: MarkerIDMode.allCases)
mutating func testBasicMarkers_extractMarkers_nonEmptyMarkerIDs(idMode: MarkerIDMode) async throws {
settings.idNamingMode = idMode

for idMode in MarkerIDMode.allCases {
settings.idNamingMode = idMode

let extractor = MarkersExtractor(settings: settings)
let extractor = MarkersExtractor(settings: settings)

// attempt to extract markers.
switch idMode {
case .timelineNameAndTimecode:
// no way case an error since timecode will always be a non-empty string.
// so just test that no error is thrown here.

// attempt to extract markers.
switch idMode {
case .timelineNameAndTimecode:
// no way case an error since timecode will always be a non-empty string.
// so just test that no error is thrown here.
do {
_ = try await extractor.extractMarkers()
} catch {
XCTFail()
}
case .name:
// expect an error here - 3rd marker has an empty Name
do {
_ = try await extractor.extractMarkers()
XCTFail("Expected error to be thrown.")
} catch {
// we want an error
}
case .notes:
// expect an error here - 2nd marker has an empty Name
do {
_ = try await extractor.extractMarkers()
XCTFail("Expected error to be thrown.")
} catch {
// we want an error
}
do {
_ = try await extractor.extractMarkers()
} catch {
#fail
}
case .name:
// expect an error here - 3rd marker has an empty Name
do {
_ = try await extractor.extractMarkers()
#fail("Expected error to be thrown.")
} catch {
// we want an error
}
case .notes:
// expect an error here - 2nd marker has an empty Name
do {
_ = try await extractor.extractMarkers()
#fail("Expected error to be thrown.")
} catch {
// we want an error
}
}
}
Expand Down
27 changes: 14 additions & 13 deletions Tests/MarkersExtractorTests/BasicMarkersOutOfClipBoundsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
//

import DAWFileKit
@testable import MarkersExtractor
import Testing
import TestingExtensions
import TimecodeKitCore
import XCTest
@testable import MarkersExtractor

final class BasicMarkersOutOfClipBoundsTests: XCTestCase {
@Suite struct BasicMarkersOutOfClipBoundsTests {
/// Ensure that markers that are out of bounds of clips are not included in extraction.
/// Also tests to make sure marker parent clip information is correct.
func testOutOfClipBounds() async throws {
@Test func outOfClipBounds() async throws {
let settings = try MarkersExtractor.Settings(
fcpxml: FCPXMLFile(fileContents: fcpxmlTestData),
outputDir: FileManager.default.temporaryDirectory
Expand Down Expand Up @@ -55,25 +56,25 @@ final class BasicMarkersOutOfClipBoundsTests: XCTestCase {

// check markers

XCTAssertEqual(markers.count, 2)
#expect(markers.count == 2)

// if the clip is the first clip on the timeline (it starts at 00:00:00:00) and
// it had been resized from its left edge to result in an out-of-boundary marker prior to
// the new clip start, the hidden marker's location

// clip 1

let marker0 = try XCTUnwrap(markers[safe: 0])
XCTAssertEqual(marker0.name, "Marker 2")
XCTAssertEqual(marker0.position, tc("00:00:07:23", at: fr))
XCTAssertEqual(marker0.parentInfo, clip1ParentInfo)
let marker0 = try #require(markers[safe: 0])
#expect(marker0.name == "Marker 2")
#expect(marker0.position == tc("00:00:07:23", at: fr))
#expect(marker0.parentInfo == clip1ParentInfo)

// clip 2

let marker1 = try XCTUnwrap(markers[safe: 1])
XCTAssertEqual(marker1.name, "Marker 5")
XCTAssertEqual(marker1.position, tc("00:00:28:18", at: fr))
XCTAssertEqual(marker1.parentInfo, clip2ParentInfo)
let marker1 = try #require(markers[safe: 1])
#expect(marker1.name == "Marker 5")
#expect(marker1.position == tc("00:00:28:18", at: fr))
#expect(marker1.parentInfo == clip2ParentInfo)
}
}

Expand Down
Loading

0 comments on commit ae8a4ef

Please sign in to comment.