From a51457ca88517fbda08801479783504448202c26 Mon Sep 17 00:00:00 2001 From: Tibor Bodecs Date: Thu, 19 Feb 2026 10:13:59 +0100 Subject: [PATCH] apply naming conventions --- Makefile | 2 +- Package.swift | 12 +- README.md | 31 +-- .../DatabaseClientMySQL.swift} | 16 +- .../DatabaseConnectionMySQL.swift} | 10 +- .../DatabaseRowMySQL.swift} | 6 +- .../DatabaseRowSequenceMySQL.swift} | 14 +- .../DatabaseTransactionErrorMySQL.swift} | 6 +- .../FeatherDatabaseMySQLTestSuite.swift} | 176 ++++++++++++++++- .../MySQLDatabaseRowSequenceTests.swift | 177 ------------------ 10 files changed, 221 insertions(+), 229 deletions(-) rename Sources/{FeatherMySQLDatabase/MySQLDatabaseClient.swift => FeatherDatabaseMySQL/DatabaseClientMySQL.swift} (88%) rename Sources/{FeatherMySQLDatabase/MySQLDatabaseConnection.swift => FeatherDatabaseMySQL/DatabaseConnectionMySQL.swift} (91%) rename Sources/{FeatherMySQLDatabase/MySQLDatabaseRow.swift => FeatherDatabaseMySQL/DatabaseRowMySQL.swift} (97%) rename Sources/{FeatherMySQLDatabase/MySQLDatabaseRowSequence.swift => FeatherDatabaseMySQL/DatabaseRowSequenceMySQL.swift} (78%) rename Sources/{FeatherMySQLDatabase/MySQLDatabaseTransactionError.swift => FeatherDatabaseMySQL/DatabaseTransactionErrorMySQL.swift} (93%) rename Tests/{FeatherMySQLDatabaseTests/FeatherMySQLDatabaseTestSuite.swift => FeatherDatabaseMySQLTests/FeatherDatabaseMySQLTestSuite.swift} (90%) delete mode 100644 Tests/FeatherMySQLDatabaseTests/MySQLDatabaseRowSequenceTests.swift diff --git a/Makefile b/Makefile index d43b126..dbd22a5 100644 --- a/Makefile +++ b/Makefile @@ -48,4 +48,4 @@ test: swift test --parallel docker-test: - docker build -t feather-mysql-database-tests . -f ./docker/tests/Dockerfile && docker run --rm feather-mysql-database-tests + docker build -t feather-database-mysql-tests . -f ./docker/tests/Dockerfile && docker run --rm feather-database-mysql-tests diff --git a/Package.swift b/Package.swift index 073691f..68b4676 100644 --- a/Package.swift +++ b/Package.swift @@ -11,7 +11,7 @@ var defaultSwiftSettings: [SwiftSetting] = // https://forums.swift.org/t/experimental-support-for-lifetime-dependencies-in-swift-6-2-and-beyond/78638 .enableExperimentalFeature("Lifetimes"), // https://github.com/swiftlang/swift/pull/65218 - .enableExperimentalFeature("AvailabilityMacro=featherMySQLDatabase 1.0:macOS 15.0, iOS 18.0, tvOS 18.0, watchOS 11.0, visionOS 2.0"), + .enableExperimentalFeature("AvailabilityMacro=FeatherDatabaseMySQL 1.0:macOS 15.0, iOS 18.0, tvOS 18.0, watchOS 11.0, visionOS 2.0"), ] #if compiler(>=6.2) @@ -23,7 +23,7 @@ defaultSwiftSettings.append( let package = Package( - name: "feather-mysql-database", + name: "feather-database-mysql", platforms: [ .macOS(.v15), .iOS(.v18), @@ -32,7 +32,7 @@ let package = Package( .visionOS(.v2), ], products: [ - .library(name: "FeatherMySQLDatabase", targets: ["FeatherMySQLDatabase"]), + .library(name: "FeatherDatabaseMySQL", targets: ["FeatherDatabaseMySQL"]), ], dependencies: [ .package(url: "https://github.com/apple/swift-log", from: "1.6.0"), @@ -42,7 +42,7 @@ let package = Package( ], targets: [ .target( - name: "FeatherMySQLDatabase", + name: "FeatherDatabaseMySQL", dependencies: [ .product(name: "Logging", package: "swift-log"), .product(name: "MySQLNIO", package: "mysql-nio"), @@ -51,9 +51,9 @@ let package = Package( swiftSettings: defaultSwiftSettings ), .testTarget( - name: "FeatherMySQLDatabaseTests", + name: "FeatherDatabaseMySQLTests", dependencies: [ - .target(name: "FeatherMySQLDatabase"), + .target(name: "FeatherDatabaseMySQL"), ], swiftSettings: defaultSwiftSettings ), diff --git a/README.md b/README.md index 1534afb..487fdd7 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# Feather MySQL Database +# Feather Database MySQL MySQL/MariaDB driver implementation for the abstract [Feather Database](https://github.com/feather-framework/feather-database) Swift API package. [ - ![Release: 1.0.0-beta.4](https://img.shields.io/badge/Release-1%2E0%2E0--beta%2E4-F05138) + ![Release: 1.0.0-beta.5](https://img.shields.io/badge/Release-1%2E0%2E0--beta%2E5-F05138) ]( - https://github.com/feather-framework/feather-mysql-database/releases/tag/1.0.0-beta.4 + https://github.com/feather-framework/feather-database-mysql/releases/tag/1.0.0-beta.5 ) ## Features @@ -36,20 +36,24 @@ MySQL/MariaDB driver implementation for the abstract [Feather Database](https:// Add the dependency to your `Package.swift`: ```swift -.package(url: "https://github.com/feather-framework/feather-mysql-database", exact: "1.0.0-beta.4"), +.package(url: "https://github.com/feather-framework/feather-database-mysql", exact: "1.0.0-beta.5"), ``` -Then add `FeatherMySQLDatabase` to your target dependencies: +Then add `FeatherDatabaseMySQL` to your target dependencies: ```swift -.product(name: "FeatherMySQLDatabase", package: "feather-mysql-database"), +.product(name: "FeatherDatabaseMySQL", package: "feather-database-mysql"), ``` ## Usage API documentation is available at the link below: -[![DocC API documentation](https://img.shields.io/badge/DocC-API_documentation-F05138)](https://feather-framework.github.io/feather-mysql-database/) +[ + ![DocC API documentation](https://img.shields.io/badge/DocC-API_documentation-F05138) +]( + https://feather-framework.github.io/feather-database-mysql/ +) Here is a brief example: @@ -60,7 +64,7 @@ import NIOCore import NIOPosix import NIOSSL import FeatherDatabase -import FeatherMySQLDatabase +import FeatherDatabaseMySQL var logger = Logger(label: "example") logger.logLevel = .info @@ -85,7 +89,7 @@ let connection = ) .get() -let database = MySQLDatabaseClient( +let database = DatabaseClientMySQL( connection: connection, logger: logger ) @@ -123,10 +127,10 @@ catch { ## Other database drivers -The following database driver implementations are available for use: +The following database client implementations are also available for use: -- [SQLite](https://github.com/feather-framework/feather-sqlite-database) -- [Postgres](https://github.com/feather-framework/feather-postgres-database) +- [SQLite](https://github.com/feather-framework/feather-database-sqlite) +- [Postgres](https://github.com/feather-framework/feather-database-postgres) ## Development @@ -139,4 +143,5 @@ The following database driver implementations are available for use: ## Contributing -[Pull requests](https://github.com/feather-framework/feather-mysql-database/pulls) are welcome. Please keep changes focused and include tests for new logic. +[Pull requests](https://github.com/feather-framework/feather-database-mysql/pulls) are welcome. Please keep changes focused and include tests for new logic. 🙏 + diff --git a/Sources/FeatherMySQLDatabase/MySQLDatabaseClient.swift b/Sources/FeatherDatabaseMySQL/DatabaseClientMySQL.swift similarity index 88% rename from Sources/FeatherMySQLDatabase/MySQLDatabaseClient.swift rename to Sources/FeatherDatabaseMySQL/DatabaseClientMySQL.swift index d095345..63d7c79 100644 --- a/Sources/FeatherMySQLDatabase/MySQLDatabaseClient.swift +++ b/Sources/FeatherDatabaseMySQL/DatabaseClientMySQL.swift @@ -1,6 +1,6 @@ // -// MySQLDatabaseClient.swift -// feather-mysql-database +// DatabaseClientMySQL.swift +// feather-database-mysql // // Created by Tibor Bödecs on 2026. 01. 10.. // @@ -12,11 +12,11 @@ import MySQLNIO /// A MySQL-backed database client. /// /// Use this client to execute queries and manage transactions on MySQL. -public struct MySQLDatabaseClient: DatabaseClient { +public struct DatabaseClientMySQL: DatabaseClient { - public typealias Connection = MySQLDatabaseConnection + public typealias Connection = DatabaseConnectionMySQL - var connection: MySQLDatabaseConnection + var connection: DatabaseConnectionMySQL var logger: Logger /// Create a MySQL database client. @@ -75,7 +75,7 @@ public struct MySQLDatabaseClient: DatabaseClient { } catch { throw DatabaseError.transaction( - MySQLTransactionError( + DatabaseTransactionErrorMySQL( beginError: error ) ) @@ -92,14 +92,14 @@ public struct MySQLDatabaseClient: DatabaseClient { } catch { throw DatabaseError.transaction( - MySQLTransactionError(commitError: error) + DatabaseTransactionErrorMySQL(commitError: error) ) } return result } catch { - var txError = MySQLTransactionError() + var txError = DatabaseTransactionErrorMySQL() if !closureHasFinished { txError.closureError = error diff --git a/Sources/FeatherMySQLDatabase/MySQLDatabaseConnection.swift b/Sources/FeatherDatabaseMySQL/DatabaseConnectionMySQL.swift similarity index 91% rename from Sources/FeatherMySQLDatabase/MySQLDatabaseConnection.swift rename to Sources/FeatherDatabaseMySQL/DatabaseConnectionMySQL.swift index ffaca68..afeaa0f 100644 --- a/Sources/FeatherMySQLDatabase/MySQLDatabaseConnection.swift +++ b/Sources/FeatherDatabaseMySQL/DatabaseConnectionMySQL.swift @@ -1,6 +1,6 @@ // -// MySQLDatabaseConnection.swift -// feather-mysql-database +// DatabaseConnectionMySQL.swift +// feather-database-mysql // // Created by Tibor Bödecs on 2026. 01. 10. // @@ -45,9 +45,9 @@ extension DatabaseQuery { } } -public struct MySQLDatabaseConnection: DatabaseConnection, Sendable { +public struct DatabaseConnectionMySQL: DatabaseConnection { - public typealias RowSequence = MySQLRowSequence + public typealias RowSequence = DatabaseRowSequenceMySQL let connection: MySQLNIO.MySQLConnection public var logger: Logging.Logger @@ -75,7 +75,7 @@ public struct MySQLDatabaseConnection: DatabaseConnection, Sendable { .get() return try await handler( - MySQLRowSequence( + DatabaseRowSequenceMySQL( elements: rows.map { .init( row: $0 diff --git a/Sources/FeatherMySQLDatabase/MySQLDatabaseRow.swift b/Sources/FeatherDatabaseMySQL/DatabaseRowMySQL.swift similarity index 97% rename from Sources/FeatherMySQLDatabase/MySQLDatabaseRow.swift rename to Sources/FeatherDatabaseMySQL/DatabaseRowMySQL.swift index 3d0e7f0..55da95c 100644 --- a/Sources/FeatherMySQLDatabase/MySQLDatabaseRow.swift +++ b/Sources/FeatherDatabaseMySQL/DatabaseRowMySQL.swift @@ -1,6 +1,6 @@ // -// MySQLDatabaseRow.swift -// feather-mysql-database +// DatabaseRowMySQL.swift +// feather-database-mysql // // Created by Tibor Bödecs on 2026. 01. 10. // @@ -8,7 +8,7 @@ import FeatherDatabase import MySQLNIO -public struct MySQLRow: DatabaseRow { +public struct DatabaseRowMySQL: DatabaseRow { var row: MySQLNIO.MySQLRow diff --git a/Sources/FeatherMySQLDatabase/MySQLDatabaseRowSequence.swift b/Sources/FeatherDatabaseMySQL/DatabaseRowSequenceMySQL.swift similarity index 78% rename from Sources/FeatherMySQLDatabase/MySQLDatabaseRowSequence.swift rename to Sources/FeatherDatabaseMySQL/DatabaseRowSequenceMySQL.swift index 3a61316..cd454c8 100644 --- a/Sources/FeatherMySQLDatabase/MySQLDatabaseRowSequence.swift +++ b/Sources/FeatherDatabaseMySQL/DatabaseRowSequenceMySQL.swift @@ -1,6 +1,6 @@ // -// MySQLDatabaseRowSequence.swift -// feather-mysql-database +// DatabaseRowSequenceMySQL.swift +// feather-database-mysql // // Created by Tibor Bödecs on 2026. 01. 10. // @@ -10,22 +10,22 @@ import FeatherDatabase /// A query result backed by MySQL rows. /// /// Use this type to iterate or collect MySQL query results. -public struct MySQLRowSequence: DatabaseRowSequence { +public struct DatabaseRowSequenceMySQL: DatabaseRowSequence { - let elements: [MySQLRow] + let elements: [DatabaseRowMySQL] /// An async iterator over MySQL rows. /// /// This iterator traverses the in-memory row list. public struct Iterator: AsyncIteratorProtocol { var index = 0 - let elements: [MySQLRow] + let elements: [DatabaseRowMySQL] /// Return the next row in the sequence. /// /// This returns `nil` after the last row. /// - Returns: The next `MySQLRow`, or `nil` when finished. - public mutating func next() async -> MySQLRow? { + public mutating func next() async -> DatabaseRowMySQL? { guard index < elements.count else { return nil } @@ -47,7 +47,7 @@ public struct MySQLRowSequence: DatabaseRowSequence { /// This returns the rows held by the result. /// - Throws: An error if collection fails. /// - Returns: An array of `MySQLRow` values. - public func collect() async throws -> [MySQLRow] { + public func collect() async throws -> [DatabaseRowMySQL] { elements } } diff --git a/Sources/FeatherMySQLDatabase/MySQLDatabaseTransactionError.swift b/Sources/FeatherDatabaseMySQL/DatabaseTransactionErrorMySQL.swift similarity index 93% rename from Sources/FeatherMySQLDatabase/MySQLDatabaseTransactionError.swift rename to Sources/FeatherDatabaseMySQL/DatabaseTransactionErrorMySQL.swift index b6255fc..c7fcd93 100644 --- a/Sources/FeatherMySQLDatabase/MySQLDatabaseTransactionError.swift +++ b/Sources/FeatherDatabaseMySQL/DatabaseTransactionErrorMySQL.swift @@ -1,6 +1,6 @@ // -// MySQLDatabaseTransactionError.swift -// feather-mysql-database +// DatabaseTransactionErrorMySQL.swift +// feather-database-mysql // // Created by Tibor Bödecs on 2026. 01. 10. // @@ -10,7 +10,7 @@ import FeatherDatabase /// Transaction error details for MySQL operations. /// /// Use this to capture errors from transaction phases. -public struct MySQLTransactionError: DatabaseTransactionError { +public struct DatabaseTransactionErrorMySQL: DatabaseTransactionError { /// The source file where the error was created. /// diff --git a/Tests/FeatherMySQLDatabaseTests/FeatherMySQLDatabaseTestSuite.swift b/Tests/FeatherDatabaseMySQLTests/FeatherDatabaseMySQLTestSuite.swift similarity index 90% rename from Tests/FeatherMySQLDatabaseTests/FeatherMySQLDatabaseTestSuite.swift rename to Tests/FeatherDatabaseMySQLTests/FeatherDatabaseMySQLTestSuite.swift index c43ff2f..e7e034a 100644 --- a/Tests/FeatherMySQLDatabaseTests/FeatherMySQLDatabaseTestSuite.swift +++ b/Tests/FeatherDatabaseMySQLTests/FeatherDatabaseMySQLTestSuite.swift @@ -1,6 +1,6 @@ // -// FeatherMySQLDatabaseTestSuite.swift -// feather-mysql-database +// FeatherDatabaseMySQLTestSuite.swift +// feather-database-mysql // // Created by Tibor Bödecs on 2026. 01. 10.. // @@ -13,7 +13,7 @@ import NIOPosix import NIOSSL import Testing -@testable import FeatherMySQLDatabase +@testable import FeatherDatabaseMySQL #if canImport(FoundationEssentials) import FoundationEssentials @@ -22,7 +22,7 @@ import Foundation #endif @Suite -struct MySQLDatabaseTestSuite { +struct FeatherDatabaseMySQLTestSuite { func randomTableSuffix() -> String { let characters = Array("abcdefghijklmnopqrstuvwxyz0123456789") @@ -35,7 +35,7 @@ struct MySQLDatabaseTestSuite { } func runUsingTestDatabaseClient( - _ closure: ((MySQLDatabaseClient) async throws -> Void) + _ closure: ((DatabaseClientMySQL) async throws -> Void) ) async throws { var logger = Logger(label: "test") logger.logLevel = .info @@ -69,7 +69,7 @@ struct MySQLDatabaseTestSuite { ) .get() - let database = MySQLDatabaseClient( + let database = DatabaseClientMySQL( connection: connection, logger: logger ) @@ -1565,4 +1565,168 @@ struct MySQLDatabaseTestSuite { } } + // MARK: - sequence tests + + @Test + func rowSequenceIteratesRowsInOrder() async throws { + try await runUsingTestDatabaseClient { database in + let suffix = randomTableSuffix() + let table = "planets_\(suffix)" + + try await database.withConnection { connection in + try await connection.run( + query: #""" + DROP TABLE IF EXISTS `\#(unescaped: table)`; + """# + ) + try await connection.run( + query: #""" + CREATE TABLE IF NOT EXISTS `\#(unescaped: table)` ( + `id` INTEGER PRIMARY KEY, + `name` TEXT + ); + """# + ) + + try await connection.run( + query: #""" + INSERT INTO `\#(unescaped: table)` (`id`, `name`) + VALUES + (1, 'Mercury'), + (2, 'Venus'); + """# + ) + + let sequence = try await connection.run( + query: #""" + SELECT * + FROM `\#(unescaped: table)` + ORDER BY `id` ASC; + """# + ) + + var iterator = sequence.makeAsyncIterator() + + let first = await iterator.next() + #expect(first != nil) + #expect( + try first?.decode(column: "name", as: String.self) + == "Mercury" + ) + + let second = await iterator.next() + #expect(second != nil) + #expect( + try second?.decode(column: "name", as: String.self) + == "Venus" + ) + + let third = await iterator.next() + #expect(third == nil) + } + } + } + + @Test + func rowSequenceCollectReturnsAllRows() async throws { + try await runUsingTestDatabaseClient { database in + let suffix = randomTableSuffix() + let table = "greetings_\(suffix)" + + try await database.withConnection { connection in + try await connection.run( + query: #""" + DROP TABLE IF EXISTS `\#(unescaped: table)`; + """# + ) + try await connection.run( + query: #""" + CREATE TABLE IF NOT EXISTS `\#(unescaped: table)` ( + `id` INTEGER PRIMARY KEY, + `name` TEXT + ); + """# + ) + + try await connection.run( + query: #""" + INSERT INTO `\#(unescaped: table)` (`id`, `name`) + VALUES + (1, 'Hello'), + (2, 'World'); + """# + ) + + let sequence = try await connection.run( + query: #""" + SELECT + `id`, + `name` + FROM `\#(unescaped: table)` + ORDER BY `id` ASC; + """# + ) + + let rows = try await sequence.collect() + #expect(rows.count == 2) + + let firstName = try rows[0] + .decode( + column: "name", + as: String.self + ) + let secondName = try rows[1] + .decode( + column: "name", + as: String.self + ) + + #expect(firstName == "Hello") + #expect(secondName == "World") + } + } + } + + @Test + func rowSequenceHandlesEmptyResults() async throws { + try await runUsingTestDatabaseClient { database in + let suffix = randomTableSuffix() + let table = "empty_rows_\(suffix)" + + try await database.withConnection { connection in + try await connection.run( + query: #""" + DROP TABLE IF EXISTS `\#(unescaped: table)`; + """# + ) + try await connection.run( + query: #""" + CREATE TABLE IF NOT EXISTS `\#(unescaped: table)` ( + `id` INTEGER PRIMARY KEY, + `name` TEXT + ); + """# + ) + + let sequence = try await connection.run( + query: #""" + SELECT + `id`, + `name` + FROM `\#(unescaped: table)` + WHERE + 1=0; + """# + ) + + let rows = try await sequence.collect() + #expect(rows.isEmpty) + + var iterator = sequence.makeAsyncIterator() + let first = await iterator.next() + #expect(first == nil) + } + } + } + } diff --git a/Tests/FeatherMySQLDatabaseTests/MySQLDatabaseRowSequenceTests.swift b/Tests/FeatherMySQLDatabaseTests/MySQLDatabaseRowSequenceTests.swift deleted file mode 100644 index 203488a..0000000 --- a/Tests/FeatherMySQLDatabaseTests/MySQLDatabaseRowSequenceTests.swift +++ /dev/null @@ -1,177 +0,0 @@ -// -// MySQLDatabaseRowSequenceTests.swift -// feather-mysql-database -// -// Created by Tibor Bödecs on 2026. 02. 09.. -// - -import FeatherDatabase -import MySQLNIO -import Testing - -@testable import FeatherMySQLDatabase - -extension MySQLDatabaseTestSuite { - - @Test - func rowSequenceIteratesRowsInOrder() async throws { - try await runUsingTestDatabaseClient { database in - let suffix = randomTableSuffix() - let table = "planets_\(suffix)" - - try await database.withConnection { connection in - try await connection.run( - query: #""" - DROP TABLE IF EXISTS `\#(unescaped: table)`; - """# - ) - try await connection.run( - query: #""" - CREATE TABLE IF NOT EXISTS `\#(unescaped: table)` ( - `id` INTEGER PRIMARY KEY, - `name` TEXT - ); - """# - ) - - try await connection.run( - query: #""" - INSERT INTO `\#(unescaped: table)` (`id`, `name`) - VALUES - (1, 'Mercury'), - (2, 'Venus'); - """# - ) - - let sequence = try await connection.run( - query: #""" - SELECT * - FROM `\#(unescaped: table)` - ORDER BY `id` ASC; - """# - ) - - var iterator = sequence.makeAsyncIterator() - - let first = await iterator.next() - #expect(first != nil) - #expect( - try first?.decode(column: "name", as: String.self) - == "Mercury" - ) - - let second = await iterator.next() - #expect(second != nil) - #expect( - try second?.decode(column: "name", as: String.self) - == "Venus" - ) - - let third = await iterator.next() - #expect(third == nil) - } - } - } - - @Test - func rowSequenceCollectReturnsAllRows() async throws { - try await runUsingTestDatabaseClient { database in - let suffix = randomTableSuffix() - let table = "greetings_\(suffix)" - - try await database.withConnection { connection in - try await connection.run( - query: #""" - DROP TABLE IF EXISTS `\#(unescaped: table)`; - """# - ) - try await connection.run( - query: #""" - CREATE TABLE IF NOT EXISTS `\#(unescaped: table)` ( - `id` INTEGER PRIMARY KEY, - `name` TEXT - ); - """# - ) - - try await connection.run( - query: #""" - INSERT INTO `\#(unescaped: table)` (`id`, `name`) - VALUES - (1, 'Hello'), - (2, 'World'); - """# - ) - - let sequence = try await connection.run( - query: #""" - SELECT - `id`, - `name` - FROM `\#(unescaped: table)` - ORDER BY `id` ASC; - """# - ) - - let rows = try await sequence.collect() - #expect(rows.count == 2) - - let firstName = try rows[0] - .decode( - column: "name", - as: String.self - ) - let secondName = try rows[1] - .decode( - column: "name", - as: String.self - ) - - #expect(firstName == "Hello") - #expect(secondName == "World") - } - } - } - - @Test - func rowSequenceHandlesEmptyResults() async throws { - try await runUsingTestDatabaseClient { database in - let suffix = randomTableSuffix() - let table = "empty_rows_\(suffix)" - - try await database.withConnection { connection in - try await connection.run( - query: #""" - DROP TABLE IF EXISTS `\#(unescaped: table)`; - """# - ) - try await connection.run( - query: #""" - CREATE TABLE IF NOT EXISTS `\#(unescaped: table)` ( - `id` INTEGER PRIMARY KEY, - `name` TEXT - ); - """# - ) - - let sequence = try await connection.run( - query: #""" - SELECT - `id`, - `name` - FROM `\#(unescaped: table)` - WHERE - 1=0; - """# - ) - - let rows = try await sequence.collect() - #expect(rows.isEmpty) - - var iterator = sequence.makeAsyncIterator() - let first = await iterator.next() - #expect(first == nil) - } - } - } -}