-
Notifications
You must be signed in to change notification settings - Fork 286
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
129 additions
and
128 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,17 @@ | ||
DEVICE ?= "iPhone 15" | ||
PLATFORM ?= "iOS,name=iPhone 16" | ||
|
||
test-ios: | ||
set -o pipefail && \ | ||
xcodebuild test \ | ||
-project Gifu.xcodeproj \ | ||
-scheme Gifu \ | ||
-destination platform="iOS Simulator,name=$(DEVICE)" \ | ||
| xcpretty | ||
-destination platform=$(PLATFORM) \ | ||
| xcbeautify | ||
|
||
test-tvos: | ||
set -o pipefail && \ | ||
xcodebuild test \ | ||
-project Gifu.xcodeproj \ | ||
-scheme Gifu \ | ||
-destination platform="tvOS Simulator,name=Apple TV" \ | ||
| xcpretty | ||
| xcbeautify |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,157 +1,157 @@ | ||
#if os(iOS) | ||
import XCTest | ||
import ImageIO | ||
@testable import Gifu | ||
|
||
private let imageData = testImageDataNamed("mugen.gif") | ||
private let staticImage = UIImage(data: imageData)! | ||
private let preloadFrameCount = 20 | ||
|
||
class DummyAnimatable: GIFAnimatable { | ||
init() {} | ||
var animator: Animator? = nil | ||
var image: UIImage? = nil | ||
var layer = CALayer() | ||
var frame: CGRect = .zero | ||
var contentMode: UIView.ContentMode = .scaleToFill | ||
func animatorHasNewFrame() {} | ||
import ImageIO | ||
import XCTest | ||
|
||
@testable import Gifu | ||
|
||
private let imageData = testImageDataNamed("mugen.gif") | ||
private let staticImage = UIImage(data: imageData)! | ||
private let preloadFrameCount = 20 | ||
|
||
class DummyAnimatable: GIFAnimatable { | ||
init() {} | ||
var animator: Animator? = nil | ||
var image: UIImage? = nil | ||
var layer = CALayer() | ||
var frame: CGRect = .zero | ||
var contentMode: UIView.ContentMode = .scaleToFill | ||
func animatorHasNewFrame() {} | ||
} | ||
|
||
@MainActor | ||
class GifuTests: XCTestCase { | ||
var animator: Animator! | ||
var originalFrameCount: Int! | ||
let delegate = DummyAnimatable() | ||
|
||
override func setUp() { | ||
super.setUp() | ||
animator = Animator(withDelegate: delegate) | ||
animator.prepareForAnimation( | ||
withGIFData: imageData, size: staticImage.size, contentMode: .scaleToFill) | ||
originalFrameCount = 44 | ||
} | ||
|
||
class GifuTests: XCTestCase { | ||
var animator: Animator! | ||
var originalFrameCount: Int! | ||
let delegate = DummyAnimatable() | ||
|
||
override func setUp() { | ||
super.setUp() | ||
animator = Animator(withDelegate: delegate) | ||
animator.prepareForAnimation( | ||
withGIFData: imageData, size: staticImage.size, contentMode: .scaleToFill) | ||
originalFrameCount = 44 | ||
} | ||
|
||
func testIsAnimatable() { | ||
XCTAssertNotNil(animator.frameStore) | ||
guard let store = animator.frameStore else { return } | ||
XCTAssertTrue(store.isAnimatable) | ||
} | ||
func testIsAnimatable() { | ||
XCTAssertNotNil(animator.frameStore) | ||
guard let store = animator.frameStore else { return } | ||
XCTAssertTrue(store.isAnimatable) | ||
} | ||
|
||
func testCurrentFrame() { | ||
XCTAssertNotNil(animator.frameStore) | ||
guard let store = animator.frameStore else { return } | ||
XCTAssertEqual(store.currentFrameIndex, 0) | ||
} | ||
func testCurrentFrame() { | ||
XCTAssertNotNil(animator.frameStore) | ||
guard let store = animator.frameStore else { return } | ||
XCTAssertEqual(store.currentFrameIndex, 0) | ||
} | ||
|
||
func testFramePreload() { | ||
XCTAssertNotNil(animator.frameStore) | ||
guard let store = animator.frameStore else { return } | ||
func testFramePreload() { | ||
XCTAssertNotNil(animator.frameStore) | ||
guard let store = animator.frameStore else { return } | ||
|
||
let expectation = self.expectation(description: "frameDuration") | ||
let expectation = self.expectation(description: "frameDuration") | ||
|
||
store.prepareFrames { | ||
let animatedFrameCount = store.animatedFrames.count | ||
XCTAssertEqual(animatedFrameCount, self.originalFrameCount) | ||
XCTAssertNotNil(store.frame(at: preloadFrameCount - 1)) | ||
XCTAssertNil(store.frame(at: preloadFrameCount + 1)?.images) | ||
XCTAssertEqual(store.currentFrameIndex, 0) | ||
store.prepareFrames { [originalFrameCount] in | ||
let animatedFrameCount = store.animatedFrames.count | ||
XCTAssertEqual(animatedFrameCount, originalFrameCount) | ||
XCTAssertNotNil(store.frame(at: preloadFrameCount - 1)) | ||
XCTAssertNil(store.frame(at: preloadFrameCount + 1)?.images) | ||
XCTAssertEqual(store.currentFrameIndex, 0) | ||
|
||
store.shouldChangeFrame(with: 1.0) { hasNewFrame in | ||
XCTAssertTrue(hasNewFrame) | ||
XCTAssertEqual(store.currentFrameIndex, 1) | ||
expectation.fulfill() | ||
} | ||
store.shouldChangeFrame(with: 1.0) { hasNewFrame in | ||
XCTAssertTrue(hasNewFrame) | ||
XCTAssertEqual(store.currentFrameIndex, 1) | ||
expectation.fulfill() | ||
} | ||
} | ||
|
||
waitForExpectations(timeout: 1.0) { error in | ||
if let error = error { | ||
print("Error: \(error.localizedDescription)") | ||
} | ||
waitForExpectations(timeout: 1.0) { error in | ||
if let error = error { | ||
print("Error: \(error.localizedDescription)") | ||
} | ||
} | ||
} | ||
|
||
func testFrameInfo() { | ||
XCTAssertNotNil(animator.frameStore) | ||
guard let store = animator.frameStore else { return } | ||
func testFrameInfo() { | ||
XCTAssertNotNil(animator.frameStore) | ||
guard let store = animator.frameStore else { return } | ||
|
||
let expectation = self.expectation(description: "testFrameInfoIsAccurate") | ||
let expectation = self.expectation(description: "testFrameInfoIsAccurate") | ||
|
||
store.prepareFrames { | ||
let frameDuration = store.frame(at: 5)?.duration ?? 0 | ||
XCTAssertTrue((frameDuration - 0.05) < 0.00001) | ||
store.prepareFrames { | ||
let frameDuration = store.frame(at: 5)?.duration ?? 0 | ||
XCTAssertTrue((frameDuration - 0.05) < 0.00001) | ||
|
||
let imageSize = store.frame(at: 5)?.size ?? CGSize.zero | ||
XCTAssertEqual(imageSize, staticImage.size) | ||
let imageSize = store.frame(at: 5)?.size ?? CGSize.zero | ||
XCTAssertEqual(imageSize, staticImage.size) | ||
|
||
expectation.fulfill() | ||
} | ||
expectation.fulfill() | ||
} | ||
|
||
waitForExpectations(timeout: 1.0) { error in | ||
if let error = error { | ||
print("Error: \(error.localizedDescription)") | ||
} | ||
waitForExpectations(timeout: 1.0) { error in | ||
if let error = error { | ||
print("Error: \(error.localizedDescription)") | ||
} | ||
} | ||
} | ||
|
||
func testFinishedStates() { | ||
animator = Animator(withDelegate: delegate) | ||
animator.prepareForAnimation( | ||
withGIFData: imageData, size: staticImage.size, contentMode: .scaleToFill, loopCount: 2) | ||
|
||
XCTAssertNotNil(animator.frameStore) | ||
guard let store = animator.frameStore else { return } | ||
func testFinishedStates() { | ||
animator = Animator(withDelegate: delegate) | ||
animator.prepareForAnimation( | ||
withGIFData: imageData, size: staticImage.size, contentMode: .scaleToFill, loopCount: 2) | ||
|
||
let expectation = self.expectation(description: "testFinishedStatesAreSetCorrectly") | ||
XCTAssertNotNil(animator.frameStore) | ||
guard let store = animator.frameStore else { return } | ||
|
||
store.prepareFrames { | ||
let animatedFrameCount = store.animatedFrames.count | ||
XCTAssertEqual(store.currentFrameIndex, 0) | ||
let expectation = self.expectation(description: "testFinishedStatesAreSetCorrectly") | ||
|
||
// Animate through all the frames (first loop) | ||
for frame in 1..<animatedFrameCount { | ||
XCTAssertFalse(store.isLoopFinished) | ||
XCTAssertFalse(store.isFinished) | ||
store.shouldChangeFrame(with: 1.0) { hasNewFrame in | ||
XCTAssertTrue(hasNewFrame) | ||
XCTAssertEqual(store.currentFrameIndex, frame) | ||
} | ||
} | ||
|
||
XCTAssertTrue(store.isLoopFinished, "First loop should be finished") | ||
XCTAssertFalse(store.isFinished, "Animation should not be finished yet") | ||
store.prepareFrames { | ||
let animatedFrameCount = store.animatedFrames.count | ||
XCTAssertEqual(store.currentFrameIndex, 0) | ||
|
||
// Animate through all the frames (first loop) | ||
for frame in 1..<animatedFrameCount { | ||
XCTAssertFalse(store.isLoopFinished) | ||
XCTAssertFalse(store.isFinished) | ||
store.shouldChangeFrame(with: 1.0) { hasNewFrame in | ||
XCTAssertTrue(hasNewFrame) | ||
XCTAssertEqual(store.currentFrameIndex, frame) | ||
} | ||
} | ||
|
||
XCTAssertEqual(store.currentFrameIndex, 0) | ||
XCTAssertTrue(store.isLoopFinished, "First loop should be finished") | ||
XCTAssertFalse(store.isFinished, "Animation should not be finished yet") | ||
|
||
// Animate through all the frames (second loop) | ||
for frame in 1..<animatedFrameCount { | ||
XCTAssertFalse(store.isLoopFinished) | ||
XCTAssertFalse(store.isFinished) | ||
store.shouldChangeFrame(with: 1.0) { hasNewFrame in | ||
XCTAssertTrue(hasNewFrame) | ||
XCTAssertEqual(store.currentFrameIndex, frame) | ||
} | ||
} | ||
store.shouldChangeFrame(with: 1.0) { hasNewFrame in | ||
XCTAssertTrue(hasNewFrame) | ||
} | ||
|
||
XCTAssertTrue(store.isLoopFinished, "Second loop should be finished") | ||
XCTAssertTrue(store.isFinished, "Animation should be finished (loopCount: 2)") | ||
XCTAssertEqual(store.currentFrameIndex, 0) | ||
|
||
expectation.fulfill() | ||
// Animate through all the frames (second loop) | ||
for frame in 1..<animatedFrameCount { | ||
XCTAssertFalse(store.isLoopFinished) | ||
XCTAssertFalse(store.isFinished) | ||
store.shouldChangeFrame(with: 1.0) { hasNewFrame in | ||
XCTAssertTrue(hasNewFrame) | ||
XCTAssertEqual(store.currentFrameIndex, frame) | ||
} | ||
} | ||
|
||
waitForExpectations(timeout: 1.0) { error in | ||
if let error = error { | ||
print("Error: \(error.localizedDescription)") | ||
} | ||
XCTAssertTrue(store.isLoopFinished, "Second loop should be finished") | ||
XCTAssertTrue(store.isFinished, "Animation should be finished (loopCount: 2)") | ||
|
||
expectation.fulfill() | ||
} | ||
|
||
waitForExpectations(timeout: 1.0) { error in | ||
if let error = error { | ||
print("Error: \(error.localizedDescription)") | ||
} | ||
} | ||
} | ||
} | ||
|
||
private func testImageDataNamed(_ name: String) -> Data { | ||
let testBundle = Bundle(for: GifuTests.self) | ||
let imagePath = testBundle.bundleURL.appendingPathComponent(name) | ||
return (try! Data(contentsOf: imagePath)) | ||
} | ||
#endif | ||
private func testImageDataNamed(_ name: String) -> Data { | ||
let testBundle = Bundle(for: GifuTests.self) | ||
let imagePath = testBundle.bundleURL.appendingPathComponent(name) | ||
return (try! Data(contentsOf: imagePath)) | ||
} |