77// Copyright © 2025 Fatbobman. All rights reserved.
88
99import Foundation
10- import Testing
1110@testable import Objects2XLSX
11+ import Testing
1212
1313/// Test data structure for async book testing
1414struct AsyncTestPerson : Sendable {
@@ -19,177 +19,173 @@ struct AsyncTestPerson: Sendable {
1919
2020@Suite ( " Book Async Write Tests " )
2121struct BookAsyncTests {
22-
2322 @Test ( " Book with async data provider writes successfully " )
24- func testBookAsyncWrite ( ) async throws {
23+ func bookAsyncWrite ( ) async throws {
2524 let tempDir = FileManager . default. temporaryDirectory
2625 let testURL = tempDir. appendingPathComponent ( " async_test.xlsx " )
27-
26+
2827 // Clean up any existing file
2928 try ? FileManager . default. removeItem ( at: testURL)
30-
29+
3130 // Create test data
3231 let people = [
3332 AsyncTestPerson ( name: " Alice " , age: 25 , isActive: true ) ,
3433 AsyncTestPerson ( name: " Bob " , age: 30 , isActive: false ) ,
3534 AsyncTestPerson ( name: " Charlie " , age: 35 , isActive: true )
3635 ]
37-
36+
3837 // Create book with async data provider
3938 let sheet = Sheet < AsyncTestPerson > (
4039 name: " Async People " ,
4140 asyncDataProvider: {
4241 // Simulate async data loading
4342 try ? await Task . sleep ( nanoseconds: 10_000_000 ) // 0.01 second
4443 return people
44+ } ) {
45+ Column ( name: " Name " , keyPath: \. name)
46+ Column ( name: " Age " , keyPath: \. age)
47+ Column ( name: " Active " , keyPath: \. isActive, booleanExpressions: . yesAndNo)
4548 }
46- ) {
47- Column ( name: " Name " , keyPath: \. name)
48- Column ( name: " Age " , keyPath: \. age)
49- Column ( name: " Active " , keyPath: \. isActive, booleanExpressions: . yesAndNo)
50- }
51-
49+
5250 let book = Book ( style: BookStyle ( ) , sheets: [ sheet. eraseToAnySheet ( ) ] )
53-
51+
5452 // Write asynchronously
5553 let outputURL = try await book. writeAsync ( to: testURL)
56-
54+
5755 // Verify file was created
5856 #expect( FileManager . default. fileExists ( atPath: outputURL. path) )
5957 #expect( outputURL. pathExtension == " xlsx " )
60-
58+
6159 // Clean up
6260 try ? FileManager . default. removeItem ( at: outputURL)
6361 }
64-
62+
6563 @Test ( " Book with mixed sync and async sheets " )
66- func testBookMixedDataProviders ( ) async throws {
64+ func bookMixedDataProviders ( ) async throws {
6765 let tempDir = FileManager . default. temporaryDirectory
6866 let testURL = tempDir. appendingPathComponent ( " mixed_test.xlsx " )
69-
67+
7068 // Clean up any existing file
7169 try ? FileManager . default. removeItem ( at: testURL)
72-
70+
7371 // Create test data
7472 let syncPeople = [
7573 AsyncTestPerson ( name: " Sync1 " , age: 20 , isActive: true ) ,
7674 AsyncTestPerson ( name: " Sync2 " , age: 25 , isActive: false )
7775 ]
78-
76+
7977 let asyncPeople = [
8078 AsyncTestPerson ( name: " Async1 " , age: 30 , isActive: true ) ,
8179 AsyncTestPerson ( name: " Async2 " , age: 35 , isActive: false )
8280 ]
83-
81+
8482 // Create book with mixed data providers
8583 let syncSheet = Sheet < AsyncTestPerson > (
8684 name: " Sync People " ,
87- dataProvider: { syncPeople }
88- ) {
85+ dataProvider: { syncPeople } )
86+ {
8987 Column ( name: " Name " , keyPath: \. name)
9088 Column ( name: " Age " , keyPath: \. age)
9189 }
92-
90+
9391 let asyncSheet = Sheet < AsyncTestPerson > (
9492 name: " Async People " ,
9593 asyncDataProvider: {
9694 try ? await Task . sleep ( nanoseconds: 5_000_000 ) // 0.005 second
9795 return asyncPeople
96+ } ) {
97+ Column ( name: " Name " , keyPath: \. name)
98+ Column ( name: " Age " , keyPath: \. age)
99+ Column ( name: " Active " , keyPath: \. isActive, booleanExpressions: . yesAndNo)
98100 }
99- ) {
100- Column ( name: " Name " , keyPath: \. name)
101- Column ( name: " Age " , keyPath: \. age)
102- Column ( name: " Active " , keyPath: \. isActive, booleanExpressions: . yesAndNo)
103- }
104-
101+
105102 let book = Book ( style: BookStyle ( ) , sheets: [
106103 syncSheet. eraseToAnySheet ( ) ,
107104 asyncSheet. eraseToAnySheet ( )
108105 ] )
109-
106+
110107 // Write asynchronously
111108 let outputURL = try await book. writeAsync ( to: testURL)
112-
109+
113110 // Verify file was created
114111 #expect( FileManager . default. fileExists ( atPath: outputURL. path) )
115112 #expect( outputURL. pathExtension == " xlsx " )
116-
113+
117114 // Clean up
118115 try ? FileManager . default. removeItem ( at: outputURL)
119116 }
120-
117+
121118 @Test ( " Book writeAsync falls back to sync for sheets without async providers " )
122- func testBookAsyncFallbackToSync ( ) async throws {
119+ func bookAsyncFallbackToSync ( ) async throws {
123120 let tempDir = FileManager . default. temporaryDirectory
124121 let testURL = tempDir. appendingPathComponent ( " fallback_test.xlsx " )
125-
122+
126123 // Clean up any existing file
127124 try ? FileManager . default. removeItem ( at: testURL)
128-
125+
129126 // Create test data
130127 let people = [
131128 AsyncTestPerson ( name: " Test1 " , age: 25 , isActive: true ) ,
132129 AsyncTestPerson ( name: " Test2 " , age: 30 , isActive: false )
133130 ]
134-
131+
135132 // Create book with only sync data provider
136133 let sheet = Sheet < AsyncTestPerson > (
137134 name: " Sync Only " ,
138- dataProvider: { people }
139- ) {
135+ dataProvider: { people } )
136+ {
140137 Column ( name: " Name " , keyPath: \. name)
141138 Column ( name: " Age " , keyPath: \. age)
142139 }
143-
140+
144141 let book = Book ( style: BookStyle ( ) , sheets: [ sheet. eraseToAnySheet ( ) ] )
145-
142+
146143 // Write asynchronously (should fall back to sync)
147144 let outputURL = try await book. writeAsync ( to: testURL)
148-
145+
149146 // Verify file was created
150147 #expect( FileManager . default. fileExists ( atPath: outputURL. path) )
151148 #expect( outputURL. pathExtension == " xlsx " )
152-
149+
153150 // Clean up
154151 try ? FileManager . default. removeItem ( at: outputURL)
155152 }
156-
153+
157154 @Test ( " Progress reporting works with async write " )
158- func testAsyncProgressReporting ( ) async throws {
155+ func asyncProgressReporting ( ) async throws {
159156 let tempDir = FileManager . default. temporaryDirectory
160157 let testURL = tempDir. appendingPathComponent ( " progress_test.xlsx " )
161-
158+
162159 // Clean up any existing file
163160 try ? FileManager . default. removeItem ( at: testURL)
164-
161+
165162 // Create test data
166163 let people = [
167164 AsyncTestPerson ( name: " Progress1 " , age: 25 , isActive: true ) ,
168165 AsyncTestPerson ( name: " Progress2 " , age: 30 , isActive: false )
169166 ]
170-
167+
171168 // Create book with async data provider
172169 let sheet = Sheet < AsyncTestPerson > (
173170 name: " Progress Test " ,
174171 asyncDataProvider: {
175172 try ? await Task . sleep ( nanoseconds: 20_000_000 ) // 0.02 second
176173 return people
174+ } ) {
175+ Column ( name: " Name " , keyPath: \. name)
176+ Column ( name: " Age " , keyPath: \. age)
177177 }
178- ) {
179- Column ( name: " Name " , keyPath: \. name)
180- Column ( name: " Age " , keyPath: \. age)
181- }
182-
178+
183179 let book = Book ( style: BookStyle ( ) , sheets: [ sheet. eraseToAnySheet ( ) ] )
184-
180+
185181 // Write asynchronously
186182 let outputURL = try await book. writeAsync ( to: testURL)
187-
183+
188184 // Verify file was created
189185 #expect( FileManager . default. fileExists ( atPath: outputURL. path) )
190186 #expect( outputURL. pathExtension == " xlsx " )
191-
187+
192188 // Clean up
193189 try ? FileManager . default. removeItem ( at: outputURL)
194190 }
195- }
191+ }
0 commit comments