forked from GraphQLSwift/DataLoader
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDataLoaderAsyncTests.swift
More file actions
115 lines (91 loc) · 3.88 KB
/
DataLoaderAsyncTests.swift
File metadata and controls
115 lines (91 loc) · 3.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
@testable import DataLoader
import NIOPosix
import XCTest
#if compiler(>=5.5) && canImport(_Concurrency)
@available(macOS 12, iOS 15, watchOS 8, tvOS 15, *)
actor Concurrent<T> {
var wrappedValue: T
func nonmutating<Returned>(_ action: (T) throws -> Returned) async rethrows -> Returned {
try action(wrappedValue)
}
func mutating<Returned>(_ action: (inout T) throws -> Returned) async rethrows -> Returned {
try action(&wrappedValue)
}
init(_ value: T) {
wrappedValue = value
}
}
/// Primary API
@available(macOS 12, iOS 15, watchOS 8, tvOS 15, *)
final class DataLoaderAsyncTests: XCTestCase {
/// Builds a really really simple data loader with async await
func testReallyReallySimpleDataLoader() async throws {
let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)
defer {
XCTAssertNoThrow(try eventLoopGroup.syncShutdownGracefully())
}
let identityLoader = DataLoader<Int, Int>(
on: eventLoopGroup.next(),
options: DataLoaderOptions(batchingEnabled: false)
) { keys async in
let task = Task {
keys.map { DataLoaderFutureValue.success($0) }
}
return await task.value
}
let value = try await identityLoader.load(key: 1, on: eventLoopGroup)
XCTAssertEqual(value, 1)
}
/// Supports loading multiple keys in one call
func testLoadingMultipleKeys() async throws {
let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)
defer {
XCTAssertNoThrow(try eventLoopGroup.syncShutdownGracefully())
}
let identityLoader = DataLoader<Int, Int>(on: eventLoopGroup.next()) { keys in
let task = Task {
keys.map { DataLoaderFutureValue.success($0) }
}
return await task.value
}
let values = try await identityLoader.loadMany(keys: [1, 2], on: eventLoopGroup)
XCTAssertEqual(values, [1, 2])
let empty = try await identityLoader.loadMany(keys: [], on: eventLoopGroup)
XCTAssertTrue(empty.isEmpty)
}
/// Batches multiple requests
func testMultipleRequests() async throws {
let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)
defer {
XCTAssertNoThrow(try eventLoopGroup.syncShutdownGracefully())
}
let loadCalls = Concurrent<[[Int]]>([])
let identityLoader = DataLoader<Int, Int>(
on: eventLoopGroup.next(),
options: DataLoaderOptions(
batchingEnabled: true,
executionPeriod: nil
)
) { keys in
await loadCalls.mutating { $0.append(keys) }
let task = Task {
keys.map { DataLoaderFutureValue.success($0) }
}
return await task.value
}
async let value1 = identityLoader.load(key: 1, on: eventLoopGroup)
async let value2 = identityLoader.load(key: 2, on: eventLoopGroup)
// Have to wait for a split second because Tasks may not be executed before this
// statement
try await Task.sleep(nanoseconds: 500_000_000)
XCTAssertNoThrow(try identityLoader.execute())
let result1 = try await value1
XCTAssertEqual(result1, 1)
let result2 = try await value2
XCTAssertEqual(result2, 2)
let calls = await loadCalls.wrappedValue
XCTAssertEqual(calls.count, 1)
XCTAssertEqual(calls.map { $0.sorted() }, [[1, 2]])
}
}
#endif