mirror of
https://github.com/kean/Nuke.git
synced 2024-11-28 12:04:01 +03:00
Update ImageCacheTests
This commit is contained in:
parent
52771a052b
commit
4e0bca9161
@ -2,94 +2,82 @@
|
||||
//
|
||||
// Copyright (c) 2015-2024 Alexander Grebenyuk (github.com/kean).
|
||||
|
||||
import XCTest
|
||||
import Foundation
|
||||
import Testing
|
||||
@testable import Nuke
|
||||
|
||||
private func _request(index: Int) -> ImageRequest {
|
||||
return ImageRequest(url: URL(string: "http://example.com/img\(index)")!)
|
||||
}
|
||||
private let request1 = _request(index: 1)
|
||||
private let request2 = _request(index: 2)
|
||||
private let request3 = _request(index: 3)
|
||||
#if canImport(UIKit)
|
||||
import UIKit
|
||||
#endif
|
||||
|
||||
class ImageCacheTests: XCTestCase, @unchecked Sendable {
|
||||
var cache: ImageCache!
|
||||
@Suite struct ImageCacheTests {
|
||||
let cache = ImageCache()
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
|
||||
cache = ImageCache()
|
||||
init() {
|
||||
cache.entryCostLimit = 2
|
||||
}
|
||||
|
||||
// MARK: - Basics
|
||||
|
||||
@MainActor
|
||||
func testCacheCreation() {
|
||||
XCTAssertEqual(cache.totalCount, 0)
|
||||
XCTAssertNil(cache[Test.request])
|
||||
@Test func cacheCreation() {
|
||||
#expect(cache.totalCount == 0)
|
||||
#expect(cache[Test.request] == nil)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testThatImageIsStored() {
|
||||
@Test func imageIsStored() {
|
||||
// When
|
||||
cache[Test.request] = Test.container
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(cache.totalCount, 1)
|
||||
XCTAssertNotNil(cache[Test.request])
|
||||
#expect(cache.totalCount == 1)
|
||||
#expect(cache[Test.request] != nil)
|
||||
}
|
||||
|
||||
// MARK: - Subscript
|
||||
|
||||
@MainActor
|
||||
func testThatImageIsStoredUsingSubscript() {
|
||||
@Test func imageIsStoredUsingSubscript() {
|
||||
// When
|
||||
cache[Test.request] = Test.container
|
||||
|
||||
// Then
|
||||
XCTAssertNotNil(cache[Test.request])
|
||||
#expect(cache[Test.request] != nil)
|
||||
}
|
||||
|
||||
// MARK: - Count
|
||||
|
||||
@MainActor
|
||||
func testThatTotalCountChanges() {
|
||||
XCTAssertEqual(cache.totalCount, 0)
|
||||
@Test func totalCountChanges() {
|
||||
#expect(cache.totalCount == 0)
|
||||
|
||||
cache[request1] = Test.container
|
||||
XCTAssertEqual(cache.totalCount, 1)
|
||||
#expect(cache.totalCount == 1)
|
||||
|
||||
cache[request2] = Test.container
|
||||
XCTAssertEqual(cache.totalCount, 2)
|
||||
#expect(cache.totalCount == 2)
|
||||
|
||||
cache[request2] = nil
|
||||
XCTAssertEqual(cache.totalCount, 1)
|
||||
#expect(cache.totalCount == 1)
|
||||
|
||||
cache[request1] = nil
|
||||
XCTAssertEqual(cache.totalCount, 0)
|
||||
#expect(cache.totalCount == 0)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testThatCountLimitChanges() {
|
||||
@Test func countLimitChanges() {
|
||||
// When
|
||||
cache.countLimit = 1
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(cache.countLimit, 1)
|
||||
#expect(cache.countLimit == 1)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testThatTTLChanges() {
|
||||
//when
|
||||
@Test func ttlChanges() {
|
||||
// when
|
||||
cache.ttl = 1
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(cache.ttl, 1)
|
||||
#expect(cache.ttl == 1)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testThatItemsAreRemoveImmediatelyWhenCountLimitIsReached() {
|
||||
@Test func itemsAreRemoveImmediatelyWhenCountLimitIsReached() {
|
||||
// Given
|
||||
cache.countLimit = 1
|
||||
|
||||
@ -98,12 +86,11 @@ class ImageCacheTests: XCTestCase, @unchecked Sendable {
|
||||
cache[request2] = Test.container
|
||||
|
||||
// Then
|
||||
XCTAssertNil(cache[request1])
|
||||
XCTAssertNotNil(cache[request2])
|
||||
#expect(cache[request1] == nil)
|
||||
#expect(cache[request2] != nil)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testTrimToCount() {
|
||||
@Test func trimToCount() {
|
||||
// Given
|
||||
cache[request1] = Test.container
|
||||
cache[request2] = Test.container
|
||||
@ -112,12 +99,11 @@ class ImageCacheTests: XCTestCase, @unchecked Sendable {
|
||||
cache.trim(toCount: 1)
|
||||
|
||||
// Then
|
||||
XCTAssertNil(cache[request1])
|
||||
XCTAssertNotNil(cache[request2])
|
||||
#expect(cache[request1] == nil)
|
||||
#expect(cache[request2] != nil)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testThatImagesAreRemovedOnCountLimitChange() {
|
||||
@Test func imagesAreRemovedOnCountLimitChange() {
|
||||
// Given
|
||||
cache.countLimit = 2
|
||||
|
||||
@ -128,39 +114,36 @@ class ImageCacheTests: XCTestCase, @unchecked Sendable {
|
||||
cache.countLimit = 1
|
||||
|
||||
// Then
|
||||
XCTAssertNil(cache[request1])
|
||||
XCTAssertNotNil(cache[request2])
|
||||
#expect(cache[request1] == nil)
|
||||
#expect(cache[request2] != nil)
|
||||
}
|
||||
|
||||
// MARK: Cost
|
||||
|
||||
#if !os(macOS)
|
||||
#if canImport(UIKit)
|
||||
|
||||
@MainActor
|
||||
func testDefaultImageCost() {
|
||||
XCTAssertEqual(cache.cost(for: ImageContainer(image: Test.image)), 1228800)
|
||||
@Test func defaultImageCost() {
|
||||
#expect(cache.cost(for: ImageContainer(image: Test.image)) == 1228800)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testThatTotalCostChanges() {
|
||||
@Test func totalCostChanges() {
|
||||
let imageCost = cache.cost(for: ImageContainer(image: Test.image))
|
||||
XCTAssertEqual(cache.totalCost, 0)
|
||||
#expect(cache.totalCost == 0)
|
||||
|
||||
cache[request1] = Test.container
|
||||
XCTAssertEqual(cache.totalCost, imageCost)
|
||||
#expect(cache.totalCost == imageCost)
|
||||
|
||||
cache[request2] = Test.container
|
||||
XCTAssertEqual(cache.totalCost, 2 * imageCost)
|
||||
#expect(cache.totalCost == 2 * imageCost)
|
||||
|
||||
cache[request2] = nil
|
||||
XCTAssertEqual(cache.totalCost, imageCost)
|
||||
#expect(cache.totalCost == imageCost)
|
||||
|
||||
cache[request1] = nil
|
||||
XCTAssertEqual(cache.totalCost, 0)
|
||||
#expect(cache.totalCost == 0)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testThatCostLimitChanged() {
|
||||
@Test func costLimitChanged() {
|
||||
// Given
|
||||
let cost = cache.cost(for: ImageContainer(image: Test.image))
|
||||
|
||||
@ -168,11 +151,10 @@ class ImageCacheTests: XCTestCase, @unchecked Sendable {
|
||||
cache.costLimit = Int(Double(cost) * 1.5)
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(cache.costLimit, Int(Double(cost) * 1.5))
|
||||
#expect(cache.costLimit == Int(Double(cost) * 1.5))
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testThatItemsAreRemoveImmediatelyWhenCostLimitIsReached() {
|
||||
@Test func itemsAreRemoveImmediatelyWhenCostLimitIsReached() {
|
||||
// Given
|
||||
let cost = cache.cost(for: ImageContainer(image: Test.image))
|
||||
cache.costLimit = Int(Double(cost) * 1.5)
|
||||
@ -182,12 +164,11 @@ class ImageCacheTests: XCTestCase, @unchecked Sendable {
|
||||
|
||||
// LRU item is released
|
||||
cache[request2] = Test.container
|
||||
XCTAssertNil(cache[request1])
|
||||
XCTAssertNotNil(cache[request2])
|
||||
#expect(cache[request1] == nil)
|
||||
#expect(cache[request2] != nil)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testEntryCostLimitEntryStored() {
|
||||
@Test func entryCostLimitEntryStored() {
|
||||
// Given
|
||||
let container = ImageContainer(image: Test.image)
|
||||
let cost = cache.cost(for: container)
|
||||
@ -198,12 +179,11 @@ class ImageCacheTests: XCTestCase, @unchecked Sendable {
|
||||
cache[Test.request] = container
|
||||
|
||||
// Then
|
||||
XCTAssertNotNil(cache[Test.request])
|
||||
XCTAssertEqual(cache.totalCount, 1)
|
||||
#expect(cache[Test.request] != nil)
|
||||
#expect(cache.totalCount == 1)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testEntryCostLimitEntryNotStored() {
|
||||
@Test func entryCostLimitEntryNotStored() {
|
||||
// Given
|
||||
let container = ImageContainer(image: Test.image)
|
||||
let cost = cache.cost(for: container)
|
||||
@ -214,12 +194,11 @@ class ImageCacheTests: XCTestCase, @unchecked Sendable {
|
||||
cache[Test.request] = container
|
||||
|
||||
// Then
|
||||
XCTAssertNil(cache[Test.request])
|
||||
XCTAssertEqual(cache.totalCount, 0)
|
||||
#expect(cache[Test.request] == nil)
|
||||
#expect(cache.totalCount == 0)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testTrimToCost() {
|
||||
@Test func trimToCost() {
|
||||
// Given
|
||||
cache.costLimit = Int.max
|
||||
|
||||
@ -231,12 +210,11 @@ class ImageCacheTests: XCTestCase, @unchecked Sendable {
|
||||
cache.trim(toCost: Int(Double(cost) * 1.5))
|
||||
|
||||
// Then
|
||||
XCTAssertNil(cache[request1])
|
||||
XCTAssertNotNil(cache[request2])
|
||||
#expect(cache[request1] == nil)
|
||||
#expect(cache[request2] != nil)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testThatImagesAreRemovedOnCostLimitChange() {
|
||||
@Test func imagesAreRemovedOnCostLimitChange() {
|
||||
// Given
|
||||
let cost = cache.cost(for: ImageContainer(image: Test.image))
|
||||
cache.costLimit = Int(Double(cost) * 2.5)
|
||||
@ -248,38 +226,35 @@ class ImageCacheTests: XCTestCase, @unchecked Sendable {
|
||||
cache.costLimit = cost
|
||||
|
||||
// Then
|
||||
XCTAssertNil(cache[request1])
|
||||
XCTAssertNotNil(cache[request2])
|
||||
#expect(cache[request1] == nil)
|
||||
#expect(cache[request2] != nil)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testImageContainerWithoutAssociatedDataCost() {
|
||||
@Test func imageContainerWithoutAssociatedDataCost() {
|
||||
// Given
|
||||
let data = Test.data(name: "cat", extension: "gif")
|
||||
let image = PlatformImage(data: data)!
|
||||
let container = ImageContainer(image: image, data: nil)
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(cache.cost(for: container), 558000)
|
||||
#expect(cache.cost(for: container) == 558000)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testImageContainerWithAssociatedDataCost() {
|
||||
@Test func imageContainerWithAssociatedDataCost() {
|
||||
// Given
|
||||
let data = Test.data(name: "cat", extension: "gif")
|
||||
let image = PlatformImage(data: data)!
|
||||
let container = ImageContainer(image: image, data: data)
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(cache.cost(for: container), 558000 + 427672)
|
||||
#expect(cache.cost(for: container) == 558000 + 427672)
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// MARK: LRU
|
||||
|
||||
@MainActor
|
||||
func testThatLeastRecentItemsAreRemoved() {
|
||||
@Test func leastRecentItemsAreRemoved() {
|
||||
// Given
|
||||
let cost = cache.cost(for: ImageContainer(image: Test.image))
|
||||
cache.costLimit = Int(Double(cost) * 2.5)
|
||||
@ -289,13 +264,12 @@ class ImageCacheTests: XCTestCase, @unchecked Sendable {
|
||||
cache[request3] = Test.container
|
||||
|
||||
// Then
|
||||
XCTAssertNil(cache[request1])
|
||||
XCTAssertNotNil(cache[request2])
|
||||
XCTAssertNotNil(cache[request3])
|
||||
#expect(cache[request1] == nil)
|
||||
#expect(cache[request2] != nil)
|
||||
#expect(cache[request3] != nil)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testThatItemsAreTouched() {
|
||||
@Test func itemsAreTouched() {
|
||||
// Given
|
||||
let cost = cache.cost(for: ImageContainer(image: Test.image))
|
||||
cache.costLimit = Int(Double(cost) * 2.5)
|
||||
@ -308,15 +282,14 @@ class ImageCacheTests: XCTestCase, @unchecked Sendable {
|
||||
cache[request3] = Test.container
|
||||
|
||||
// Then
|
||||
XCTAssertNotNil(cache[request1])
|
||||
XCTAssertNil(cache[request2])
|
||||
XCTAssertNotNil(cache[request3])
|
||||
#expect(cache[request1] != nil)
|
||||
#expect(cache[request2] == nil)
|
||||
#expect(cache[request3] != nil)
|
||||
}
|
||||
|
||||
// MARK: Misc
|
||||
|
||||
@MainActor
|
||||
func testRemoveAll() {
|
||||
@Test func removeAll() {
|
||||
// GIVEN
|
||||
cache[request1] = Test.container
|
||||
cache[request2] = Test.container
|
||||
@ -325,13 +298,12 @@ class ImageCacheTests: XCTestCase, @unchecked Sendable {
|
||||
cache.removeAll()
|
||||
|
||||
// THEN
|
||||
XCTAssertEqual(cache.totalCount, 0)
|
||||
XCTAssertEqual(cache.totalCost, 0)
|
||||
#expect(cache.totalCount == 0)
|
||||
#expect(cache.totalCost == 0)
|
||||
}
|
||||
|
||||
#if os(iOS) || os(tvOS) || os(visionOS)
|
||||
@MainActor
|
||||
func testThatSomeImagesAreRemovedOnDidEnterBackground() async {
|
||||
#if canImport(UIKit)
|
||||
@Test @MainActor func someImagesAreRemovedOnDidEnterBackground() async {
|
||||
// GIVEN
|
||||
cache.costLimit = Int.max
|
||||
cache.countLimit = 10 // 1 out of 10 images should remain
|
||||
@ -339,20 +311,19 @@ class ImageCacheTests: XCTestCase, @unchecked Sendable {
|
||||
for i in 0..<10 {
|
||||
cache[_request(index: i)] = Test.container
|
||||
}
|
||||
XCTAssertEqual(cache.totalCount, 10)
|
||||
#expect(cache.totalCount == 10)
|
||||
|
||||
// WHEN
|
||||
let task = Task { @MainActor in
|
||||
NotificationCenter.default.post(name: UIApplication.didEnterBackgroundNotification, object: nil)
|
||||
|
||||
// THEN
|
||||
XCTAssertEqual(cache.totalCount, 1)
|
||||
#expect(cache.totalCount == 1)
|
||||
}
|
||||
await task.value
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testThatSomeImagesAreRemovedBasedOnCostOnDidEnterBackground() async {
|
||||
@Test @MainActor func someImagesAreRemovedBasedOnCostOnDidEnterBackground() async {
|
||||
// GIVEN
|
||||
let cost = cache.cost(for: ImageContainer(image: Test.image))
|
||||
cache.costLimit = cost * 10
|
||||
@ -362,62 +333,66 @@ class ImageCacheTests: XCTestCase, @unchecked Sendable {
|
||||
let request = ImageRequest(url: URL(string: "http://example.com/img\(index)")!)
|
||||
cache[request] = Test.container
|
||||
}
|
||||
XCTAssertEqual(cache.totalCount, 10)
|
||||
#expect(cache.totalCount == 10)
|
||||
|
||||
// WHEN
|
||||
let task = Task { @MainActor in
|
||||
NotificationCenter.default.post(name: UIApplication.didEnterBackgroundNotification, object: nil)
|
||||
|
||||
// THEN
|
||||
XCTAssertEqual(cache.totalCount, 1)
|
||||
#expect(cache.totalCount == 1)
|
||||
}
|
||||
await task.value
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
class InternalCacheTTLTests: XCTestCase {
|
||||
@Suite struct InternalCacheTTLTests {
|
||||
let cache = Cache<Int, Int>(costLimit: 1000, countLimit: 1000)
|
||||
|
||||
// MARK: TTL
|
||||
|
||||
@MainActor
|
||||
func testTTL() {
|
||||
@Test func ttl() {
|
||||
// Given
|
||||
cache.set(1, forKey: 1, cost: 1, ttl: 0.05) // 50 ms
|
||||
XCTAssertNotNil(cache.value(forKey: 1))
|
||||
#expect(cache.value(forKey: 1) != nil)
|
||||
|
||||
// When
|
||||
usleep(55 * 1000)
|
||||
|
||||
// Then
|
||||
XCTAssertNil(cache.value(forKey: 1))
|
||||
#expect(cache.value(forKey: 1) == nil)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testDefaultTTLIsUsed() {
|
||||
@Test func defaultTTLIsUsed() {
|
||||
// Given
|
||||
cache.conf.ttl = 0.05// 50 ms
|
||||
cache.set(1, forKey: 1, cost: 1)
|
||||
XCTAssertNotNil(cache.value(forKey: 1))
|
||||
#expect(cache.value(forKey: 1) != nil)
|
||||
|
||||
// When
|
||||
usleep(55 * 1000)
|
||||
|
||||
// Then
|
||||
XCTAssertNil(cache.value(forKey: 1))
|
||||
#expect(cache.value(forKey: 1) == nil)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testDefaultToNonExpiringEntries() {
|
||||
@Test func defaultToNonExpiringEntries() {
|
||||
// Given
|
||||
cache.set(1, forKey: 1, cost: 1)
|
||||
XCTAssertNotNil(cache.value(forKey: 1))
|
||||
#expect(cache.value(forKey: 1) != nil)
|
||||
|
||||
// When
|
||||
usleep(55 * 1000)
|
||||
|
||||
// Then
|
||||
XCTAssertNotNil(cache.value(forKey: 1))
|
||||
#expect(cache.value(forKey: 1) != nil)
|
||||
}
|
||||
}
|
||||
|
||||
private func _request(index: Int) -> ImageRequest {
|
||||
return ImageRequest(url: URL(string: "http://example.com/img\(index)")!)
|
||||
}
|
||||
private let request1 = _request(index: 1)
|
||||
private let request2 = _request(index: 2)
|
||||
private let request3 = _request(index: 3)
|
||||
|
Loading…
Reference in New Issue
Block a user