diff --git a/Tests/AppTests/RSSTests.swift b/Tests/AppTests/RSSTests.swift index cd04caaf9..dde77d14e 100644 --- a/Tests/AppTests/RSSTests.swift +++ b/Tests/AppTests/RSSTests.swift @@ -12,26 +12,28 @@ // See the License for the specific language governing permissions and // limitations under the License. +import Foundation + @testable import App import Dependencies import SnapshotTesting -import XCTVapor +import Testing -class RSSTests: SnapshotTestCase { +@Suite struct RSSTests { - func test_recentPackage_rssGuid() throws { + @Test func recentPackage_rssGuid() throws { let recentPackage = RecentPackage.mock(repositoryOwner: "owner", repositoryName: "name") - XCTAssertEqual(recentPackage.rssGuid, "owner/name") + #expect(recentPackage.rssGuid == "owner/name") } - func test_recentRelease_rssGuid() throws { + @Test func recentRelease_rssGuid() throws { let recentRelease = RecentRelease.mock(repositoryOwner: "owner", repositoryName: "name", version: "version") - XCTAssertEqual(recentRelease.rssGuid, "owner/name/version") + #expect(recentRelease.rssGuid == "owner/name/version") } - func test_render_item() throws { + @Test func render_item() throws { let item = RecentPackage.mock().rssItem // MUT + validation @@ -39,7 +41,7 @@ class RSSTests: SnapshotTestCase { as: .init(pathExtension: "xml", diffing: .lines)) } - func test_render_feed() throws { + @Test func render_feed() throws { // Test generated feed. The result should validate successfully // on https://validator.w3.org/feed/check.cgi let feed = RSSFeed(title: "feed title", description: "feed description", @@ -65,108 +67,60 @@ class RSSTests: SnapshotTestCase { as: .init(pathExtension: "xml", diffing: .lines)) } - @MainActor - func test_recentPackages() async throws { - // setup - for idx in 1...10 { - let pkg = Package(id: UUID(), url: "\(idx)".asGithubUrl.url) - try await pkg.save(on: app.db) - // re-write creation date to something stable for snapshotting - pkg.createdAt = Date(timeIntervalSince1970: TimeInterval(100*idx)) - try await pkg.save(on: app.db) - try await Repository(package: pkg, - name: "pkg-\(idx)", - owner: "owner-\(idx)", - summary: "Summary").create(on: app.db) - try await Version(package: pkg, packageName: "pkg-\(idx)").save(on: app.db) - } - // make sure to refresh the materialized view - try await RecentPackage.refresh(on: app.db) + @Test func recentPackages() async throws { + try await withApp { app in + // setup + for idx in 1...10 { + let pkg = Package(id: UUID(), url: "\(idx)".asGithubUrl.url) + try await pkg.save(on: app.db) + // re-write creation date to something stable for snapshotting + pkg.createdAt = Date(timeIntervalSince1970: TimeInterval(100*idx)) + try await pkg.save(on: app.db) + try await Repository(package: pkg, + name: "pkg-\(idx)", + owner: "owner-\(idx)", + summary: "Summary").create(on: app.db) + try await Version(package: pkg, packageName: "pkg-\(idx)").save(on: app.db) + } + // make sure to refresh the materialized view + try await RecentPackage.refresh(on: app.db) - // MUT - let feed = try await RSSFeed.recentPackages(on: app.db, limit: 8) + // MUT + let feed = try await RSSFeed.recentPackages(on: app.db, limit: 8) - // validation - assertSnapshot(of: feed.rss.render(indentedBy: .spaces(2)), - as: .init(pathExtension: "xml", diffing: .lines)) + // validation + assertSnapshot(of: feed.rss.render(indentedBy: .spaces(2)), + as: .init(pathExtension: "xml", diffing: .lines)) + } } - func test_Query_RecentRelease_filter() throws { + @Test func Query_RecentRelease_filter() throws { do { let query = RSSFeed.Query(major: true, minor: nil, patch: false, pre: nil) - XCTAssertEqual(query.filter, [.major]) + #expect(query.filter == [.major]) } do { let query = RSSFeed.Query(major: nil, minor: nil, patch: false, pre: nil) - XCTAssertEqual(query.filter, .all) - } - } - - @MainActor - func test_recentReleases() async throws { - // setup - for idx in 1...10 { - let pkg = Package(id: UUID(), url: "\(idx)".asGithubUrl.url) - try await pkg.save(on: app.db) - try await Repository(package: pkg, - name: "pkg-\(idx)", - owner: "owner-\(idx)", - summary: "Summary").create(on: app.db) - try await Version(package: pkg, - commitDate: Date(timeIntervalSince1970: TimeInterval(idx)), - packageName: "pkg-\(idx)", - reference: .tag(.init(idx, 0, 0), "\(idx).0.0"), - releaseNotes: "Awesome Release Notes", - releaseNotesHTML: "

Awesome Release Notes

", - url: "https://example.com/release-url") - .save(on: app.db) - } - // make sure to refresh the materialized view - try await RecentRelease.refresh(on: app.db) - - // MUT - let feed = try await RSSFeed.recentReleases(on: app.db, limit: 8) - - // validation - assertSnapshot(of: feed.rss.render(indentedBy: .spaces(2)), - as: .init(pathExtension: "xml", diffing: .lines)) - } - - func test_recentPackages_route() throws { - try withDependencies { - $0.httpClient.postPlausibleEvent = App.HTTPClient.noop - } operation: { - // Test request handler - try app.test(.GET, "packages.rss", afterResponse: { res in - XCTAssertEqual(res.status, .ok) - XCTAssertEqual(res.content.contentType, - .some(.init(type: "application", subType: "rss+xml"))) - }) + #expect(query.filter == .all) } } - func test_recentReleases_route_all() async throws { - try await withDependencies { - $0.httpClient.postPlausibleEvent = App.HTTPClient.noop - } operation: { - // Test request handler - without parameters (all) + @Test func recentReleases() async throws { + try await withApp { app in // setup - // see RecentViewsTests.test_recentReleases_filter for filter results for idx in 1...10 { - let major = idx / 3 // 0, 0, 1, 1, 1, 2, 2, 2, 3, 3 - let minor = idx % 3 // 1, 2, 0, 1, 2, 0, 1, 2, 0, 1 - let patch = idx % 2 // 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 let pkg = Package(id: UUID(), url: "\(idx)".asGithubUrl.url) try await pkg.save(on: app.db) try await Repository(package: pkg, name: "pkg-\(idx)", owner: "owner-\(idx)", - summary: "Summary") - .create(on: app.db) + summary: "Summary").create(on: app.db) try await Version(package: pkg, commitDate: Date(timeIntervalSince1970: TimeInterval(idx)), packageName: "pkg-\(idx)", - reference: .tag(.init(major, minor, patch)), + reference: .tag(.init(idx, 0, 0), "\(idx).0.0"), + releaseNotes: "Awesome Release Notes", + releaseNotesHTML: "

Awesome Release Notes

", url: "https://example.com/release-url") .save(on: app.db) } @@ -174,135 +128,190 @@ class RSSTests: SnapshotTestCase { try await RecentRelease.refresh(on: app.db) // MUT - try await app.test(.GET, "releases.rss", afterResponse: { @MainActor res async in - XCTAssertEqual(res.status, .ok) - XCTAssertEqual(res.content.contentType, - .some(.init(type: "application", subType: "rss+xml"))) - // validation - assertSnapshot(of: String(decoding: res.body.readableBytesView, as: UTF8.self), - as: .init(pathExtension: "xml", diffing: .lines)) - }) + let feed = try await RSSFeed.recentReleases(on: app.db, limit: 8) + + // validation + assertSnapshot(of: feed.rss.render(indentedBy: .spaces(2)), + as: .init(pathExtension: "xml", diffing: .lines)) } } - func test_recentReleases_route_major() async throws { + @Test func recentPackages_route() async throws { + // Test request handler try await withDependencies { $0.httpClient.postPlausibleEvent = App.HTTPClient.noop } operation: { - // Test request handler - major releases only - // setup - // see RecentViewsTests.test_recentReleases_filter for filter results - for idx in 1...10 { - let major = idx / 3 // 0, 0, 1, 1, 1, 2, 2, 2, 3, 3 - let minor = idx % 3 // 1, 2, 0, 1, 2, 0, 1, 2, 0, 1 - let patch = idx % 2 // 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 - let pkg = Package(id: UUID(), url: "\(idx)".asGithubUrl.url) - try await pkg.save(on: app.db) - try await Repository(package: pkg, - name: "pkg-\(idx)", - owner: "owner-\(idx)", - summary: "Summary") - .create(on: app.db) - try await Version(package: pkg, - commitDate: Date(timeIntervalSince1970: TimeInterval(idx)), - packageName: "pkg-\(idx)", - reference: .tag(.init(major, minor, patch)), - url: "https://example.com/release-url") - .save(on: app.db) + try await withApp { app in + try await app.test(.GET, "packages.rss", afterResponse: { res async in + #expect(res.status == .ok) + #expect(res.content.contentType == .some(.init(type: "application", subType: "rss+xml"))) + }) } - // make sure to refresh the materialized view - try await RecentRelease.refresh(on: app.db) + } + } - // MUT - try await app.test(.GET, "releases.rss?major=true", afterResponse: { @MainActor res async in - XCTAssertEqual(res.status, .ok) - XCTAssertEqual(res.content.contentType, - .some(.init(type: "application", subType: "rss+xml"))) - // validation - assertSnapshot(of: String(decoding: res.body.readableBytesView, as: UTF8.self), - as: .init(pathExtension: "xml", diffing: .lines)) - }) + @Test func recentReleases_route_all() async throws { + // Test request handler - without parameters (all) + try await withDependencies { + $0.httpClient.postPlausibleEvent = App.HTTPClient.noop + } operation: { + try await withApp { app in + // setup + // see RecentViewsTests.test_recentReleases_filter for filter results + for idx in 1...10 { + let major = idx / 3 // 0, 0, 1, 1, 1, 2, 2, 2, 3, 3 + let minor = idx % 3 // 1, 2, 0, 1, 2, 0, 1, 2, 0, 1 + let patch = idx % 2 // 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 + let pkg = Package(id: UUID(), url: "\(idx)".asGithubUrl.url) + try await pkg.save(on: app.db) + try await Repository(package: pkg, + name: "pkg-\(idx)", + owner: "owner-\(idx)", + summary: "Summary") + .create(on: app.db) + try await Version(package: pkg, + commitDate: Date(timeIntervalSince1970: TimeInterval(idx)), + packageName: "pkg-\(idx)", + reference: .tag(.init(major, minor, patch)), + url: "https://example.com/release-url") + .save(on: app.db) + } + // make sure to refresh the materialized view + try await RecentRelease.refresh(on: app.db) + + // MUT + try await app.test(.GET, "releases.rss", afterResponse: { @MainActor res async in + #expect(res.status == .ok) + #expect(res.content.contentType == .some(.init(type: "application", subType: "rss+xml"))) + // validation + assertSnapshot(of: String(decoding: res.body.readableBytesView, as: UTF8.self), + as: .init(pathExtension: "xml", diffing: .lines)) + }) + } } } - func test_recentReleases_route_majorMinor() async throws { + @Test func recentReleases_route_major() async throws { + // Test request handler - major releases only try await withDependencies { $0.httpClient.postPlausibleEvent = App.HTTPClient.noop } operation: { - // Test request handler - major & minor releases only - // setup - // see RecentViewsTests.test_recentReleases_filter for filter results - for idx in 1...10 { - let major = idx / 3 // 0, 0, 1, 1, 1, 2, 2, 2, 3, 3 - let minor = idx % 3 // 1, 2, 0, 1, 2, 0, 1, 2, 0, 1 - let patch = idx % 2 // 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 - let pkg = Package(id: UUID(), url: "\(idx)".asGithubUrl.url) - try await pkg.save(on: app.db) - try await Repository(package: pkg, - name: "pkg-\(idx)", - owner: "owner-\(idx)", - summary: "Summary") - .create(on: app.db) - try await Version(package: pkg, - commitDate: Date(timeIntervalSince1970: TimeInterval(idx)), - packageName: "pkg-\(idx)", - reference: .tag(.init(major, minor, patch)), - url: "https://example.com/release-url") - .save(on: app.db) + try await withApp { app in + // setup + // see RecentViewsTests.test_recentReleases_filter for filter results + for idx in 1...10 { + let major = idx / 3 // 0, 0, 1, 1, 1, 2, 2, 2, 3, 3 + let minor = idx % 3 // 1, 2, 0, 1, 2, 0, 1, 2, 0, 1 + let patch = idx % 2 // 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 + let pkg = Package(id: UUID(), url: "\(idx)".asGithubUrl.url) + try await pkg.save(on: app.db) + try await Repository(package: pkg, + name: "pkg-\(idx)", + owner: "owner-\(idx)", + summary: "Summary") + .create(on: app.db) + try await Version(package: pkg, + commitDate: Date(timeIntervalSince1970: TimeInterval(idx)), + packageName: "pkg-\(idx)", + reference: .tag(.init(major, minor, patch)), + url: "https://example.com/release-url") + .save(on: app.db) + } + // make sure to refresh the materialized view + try await RecentRelease.refresh(on: app.db) + + // MUT + try await app.test(.GET, "releases.rss?major=true", afterResponse: { @MainActor res async in + #expect(res.status == .ok) + #expect(res.content.contentType == .some(.init(type: "application", subType: "rss+xml"))) + // validation + assertSnapshot(of: String(decoding: res.body.readableBytesView, as: UTF8.self), + as: .init(pathExtension: "xml", diffing: .lines)) + }) } - // make sure to refresh the materialized view - try await RecentRelease.refresh(on: app.db) + } + } - // MUT - try await app.test(.GET, "releases.rss?major=true&minor=true", afterResponse: { @MainActor res async in - XCTAssertEqual(res.status, .ok) - XCTAssertEqual(res.content.contentType, - .some(.init(type: "application", subType: "rss+xml"))) - // validation - assertSnapshot(of: String(decoding: res.body.readableBytesView, as: UTF8.self), - as: .init(pathExtension: "xml", diffing: .lines)) - }) + @Test func recentReleases_route_majorMinor() async throws { + // Test request handler - major & minor releases only + try await withDependencies { + $0.httpClient.postPlausibleEvent = App.HTTPClient.noop + } operation: { + try await withApp { app in + // setup + // see RecentViewsTests.test_recentReleases_filter for filter results + for idx in 1...10 { + let major = idx / 3 // 0, 0, 1, 1, 1, 2, 2, 2, 3, 3 + let minor = idx % 3 // 1, 2, 0, 1, 2, 0, 1, 2, 0, 1 + let patch = idx % 2 // 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 + let pkg = Package(id: UUID(), url: "\(idx)".asGithubUrl.url) + try await pkg.save(on: app.db) + try await Repository(package: pkg, + name: "pkg-\(idx)", + owner: "owner-\(idx)", + summary: "Summary") + .create(on: app.db) + try await Version(package: pkg, + commitDate: Date(timeIntervalSince1970: TimeInterval(idx)), + packageName: "pkg-\(idx)", + reference: .tag(.init(major, minor, patch)), + url: "https://example.com/release-url") + .save(on: app.db) + } + // make sure to refresh the materialized view + try await RecentRelease.refresh(on: app.db) + + // MUT + try await app.test(.GET, "releases.rss?major=true&minor=true", afterResponse: { @MainActor res async in + #expect(res.status == .ok) + #expect(res.content.contentType == .some(.init(type: "application", subType: "rss+xml"))) + // validation + assertSnapshot(of: String(decoding: res.body.readableBytesView, as: UTF8.self), + as: .init(pathExtension: "xml", diffing: .lines)) + }) + } } } - func test_recentReleases_route_preRelease() async throws { + @Test func recentReleases_route_preRelease() async throws { + // Test request handler - pre-releases only try await withDependencies { $0.httpClient.postPlausibleEvent = App.HTTPClient.noop } operation: { - // Test request handler - pre-releases only - // setup - // see RecentViewsTests.test_recentReleases_filter for filter results - for idx in 1...12 { - let major = idx / 3 // 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4 - let minor = idx % 3 // 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0 - let patch = idx % 2 // 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 - let pre = idx <= 10 ? "" : "b1" - let pkg = Package(id: UUID(), url: "\(idx)".asGithubUrl.url) - try await pkg.save(on: app.db) - try await Repository(package: pkg, - name: "pkg-\(idx)", - owner: "owner-\(idx)", - summary: "Summary") - .create(on: app.db) - try await Version(package: pkg, - commitDate: Date(timeIntervalSince1970: TimeInterval(idx)), - packageName: "pkg-\(idx)", - reference: .tag(.init(major, minor, patch, pre)), - url: "https://example.com/release-url") - .save(on: app.db) + try await withApp { app in + // setup + // see RecentViewsTests.test_recentReleases_filter for filter results + for idx in 1...12 { + let major = idx / 3 // 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4 + let minor = idx % 3 // 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0 + let patch = idx % 2 // 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 + let pre = idx <= 10 ? "" : "b1" + let pkg = Package(id: UUID(), url: "\(idx)".asGithubUrl.url) + try await pkg.save(on: app.db) + try await Repository(package: pkg, + name: "pkg-\(idx)", + owner: "owner-\(idx)", + summary: "Summary") + .create(on: app.db) + try await Version(package: pkg, + commitDate: Date(timeIntervalSince1970: TimeInterval(idx)), + packageName: "pkg-\(idx)", + reference: .tag(.init(major, minor, patch, pre)), + url: "https://example.com/release-url") + .save(on: app.db) + } + // make sure to refresh the materialized view + try await RecentRelease.refresh(on: app.db) + + // MUT + try await app.test(.GET, "releases.rss?pre=true", afterResponse: { @MainActor res async in + #expect(res.status == .ok) + #expect(res.content.contentType == .some(.init(type: "application", subType: "rss+xml"))) + // validation + assertSnapshot(of: String(decoding: res.body.readableBytesView, as: UTF8.self), + as: .init(pathExtension: "xml", diffing: .lines)) + }) } - // make sure to refresh the materialized view - try await RecentRelease.refresh(on: app.db) - - // MUT - try await app.test(.GET, "releases.rss?pre=true", afterResponse: { @MainActor res async in - XCTAssertEqual(res.status, .ok) - XCTAssertEqual(res.content.contentType, - .some(.init(type: "application", subType: "rss+xml"))) - // validation - assertSnapshot(of: String(decoding: res.body.readableBytesView, as: UTF8.self), - as: .init(pathExtension: "xml", diffing: .lines)) - }) } } diff --git a/Tests/AppTests/S3StoreExtensionTests.swift b/Tests/AppTests/S3StoreExtensionTests.swift index 89ce62cf2..f1371cd7f 100644 --- a/Tests/AppTests/S3StoreExtensionTests.swift +++ b/Tests/AppTests/S3StoreExtensionTests.swift @@ -12,26 +12,25 @@ // See the License for the specific language governing permissions and // limitations under the License. -import XCTest - @testable import App import Dependencies import S3Store +import Testing -class S3StoreExtensionTests: XCTestCase { +@Suite struct S3StoreExtensionTests { - func test_Key_readme() throws { + @Test func Key_readme() throws { try withDependencies { $0.environment.awsReadmeBucket = { "awsReadmeBucket" } } operation: { let imageKey = try S3Store.Key.readme(owner: "owner", repository: "repository", imageUrl: "https://example.com/image/example-image.png") - XCTAssertEqual(imageKey.s3Uri, "s3://awsReadmeBucket/owner/repository/example-image.png") + #expect(imageKey.s3Uri == "s3://awsReadmeBucket/owner/repository/example-image.png") let readmeKey = try S3Store.Key.readme(owner: "owner", repository: "repository") - XCTAssertEqual(readmeKey.s3Uri, "s3://awsReadmeBucket/owner/repository/readme.html") + #expect(readmeKey.s3Uri == "s3://awsReadmeBucket/owner/repository/readme.html") } } diff --git a/Tests/AppTests/ScoreTests.swift b/Tests/AppTests/ScoreTests.swift index 85ba66063..4cc98c4df 100644 --- a/Tests/AppTests/ScoreTests.swift +++ b/Tests/AppTests/ScoreTests.swift @@ -12,235 +12,211 @@ // See the License for the specific language governing permissions and // limitations under the License. -import XCTest - @testable import App -import Dependencies +import DependenciesTestSupport +import Testing -class ScoreTests: AppTestCase { +@Suite struct ScoreTests { - func test_computeBreakdown() throws { - withDependencies { - $0.date.now = .t0 - } operation: { - XCTAssertEqual(Score.computeBreakdown(.init(licenseKind: .none, - releaseCount: 0, - likeCount: 0, - isArchived: false, - numberOfDependencies: nil, - lastActivityAt: .t0.adding(days: -400), - hasDocumentation: false, - hasReadme: false, - numberOfContributors: 0, - hasTestTargets: false)).score, - 20) - XCTAssertEqual(Score.computeBreakdown(.init(licenseKind: .incompatibleWithAppStore, - releaseCount: 0, - likeCount: 0, - isArchived: false, - numberOfDependencies: nil, - lastActivityAt: .t0.adding(days: -400), - hasDocumentation: false, - hasReadme: false, - numberOfContributors: 0, - hasTestTargets: false)).score, - 23) - XCTAssertEqual(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, - releaseCount: 0, - likeCount: 0, - isArchived: false, - numberOfDependencies: nil, - lastActivityAt: .t0.adding(days: -400), - hasDocumentation: false, - hasReadme: false, - numberOfContributors: 0, - hasTestTargets: false)).score, - 30) - XCTAssertEqual(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, - releaseCount: 10, - likeCount: 0, - isArchived: false, - numberOfDependencies: nil, - lastActivityAt: .t0.adding(days: -400), - hasDocumentation: false, - hasReadme: false, - numberOfContributors: 0, - hasTestTargets: false)).score, - 40) - XCTAssertEqual(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, - releaseCount: 10, - likeCount: 50, - isArchived: false, - numberOfDependencies: nil, - lastActivityAt: .t0.adding(days: -400), - hasDocumentation: false, - hasReadme: false, - numberOfContributors: 0, - hasTestTargets: false)).score, - 50) - XCTAssertEqual(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, - releaseCount: 10, - likeCount: 50, - isArchived: true, - numberOfDependencies: nil, - lastActivityAt: .t0.adding(days: -400), - hasDocumentation: false, - hasReadme: false, - numberOfContributors: 0, - hasTestTargets: false)).score, - 30) - XCTAssertEqual(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, - releaseCount: 20, - likeCount: 20_000, - isArchived: false, - numberOfDependencies: nil, - lastActivityAt: .t0.adding(days: -400), - hasDocumentation: false, - hasReadme: false, - numberOfContributors: 0, - hasTestTargets: false)).score, - 87) - XCTAssertEqual(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, - releaseCount: 20, - likeCount: 20_000, - isArchived: false, - numberOfDependencies: 4, - lastActivityAt: .t0.adding(days: -400), - hasDocumentation: false, - hasReadme: false, - numberOfContributors: 0, - hasTestTargets: false)).score, - 89) - XCTAssertEqual(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, - releaseCount: 20, - likeCount: 20_000, - isArchived: false, - numberOfDependencies: 2, - lastActivityAt: .t0.adding(days: -400), - hasDocumentation: false, - hasReadme: false, - numberOfContributors: 0, - hasTestTargets: false)).score, - 92) - XCTAssertEqual(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, - releaseCount: 20, - likeCount: 20_000, - isArchived: false, - numberOfDependencies: 2, - lastActivityAt: .t0.adding(days: -400), - hasDocumentation: false, - hasReadme: false, - numberOfContributors: 0, - hasTestTargets: false)).score, - 92) - XCTAssertEqual(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, - releaseCount: 20, - likeCount: 20_000, - isArchived: false, - numberOfDependencies: 2, - lastActivityAt: .t0.adding(days: -300), - hasDocumentation: false, - hasReadme: false, - numberOfContributors: 0, - hasTestTargets: false)).score, - 97) - XCTAssertEqual(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, - releaseCount: 20, - likeCount: 20_000, - isArchived: false, - numberOfDependencies: 2, - lastActivityAt: .t0.adding(days: -100), - hasDocumentation: false, - hasReadme: false, - numberOfContributors: 0, - hasTestTargets: false)).score, - 102) - XCTAssertEqual(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, - releaseCount: 20, - likeCount: 20_000, - isArchived: false, - numberOfDependencies: 2, - lastActivityAt: .t0.adding(days: -10), - hasDocumentation: false, - hasReadme: false, - numberOfContributors: 0, - hasTestTargets: false)).score, - 107) - XCTAssertEqual(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, - releaseCount: 20, - likeCount: 20_000, - isArchived: false, - numberOfDependencies: 2, - lastActivityAt: .t0.adding(days: -10), - hasDocumentation: true, - hasReadme: false, - numberOfContributors: 0, - hasTestTargets: false)).score, - 122) - XCTAssertEqual(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, - releaseCount: 20, - likeCount: 20_000, - isArchived: false, - numberOfDependencies: 2, - lastActivityAt: .t0.adding(days: -10), - hasDocumentation: true, - hasReadme: false, - numberOfContributors: 5, - hasTestTargets: false)).score, - 127) - XCTAssertEqual(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, - releaseCount: 20, - likeCount: 20_000, - isArchived: false, - numberOfDependencies: 2, - lastActivityAt: .t0.adding(days: -10), - hasDocumentation: true, - hasReadme: false, - numberOfContributors: 20, - hasTestTargets: false)).score, - 132) - XCTAssertEqual(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, - releaseCount: 20, - likeCount: 20_000, - isArchived: false, - numberOfDependencies: 2, - lastActivityAt: .t0.adding(days: -10), - hasDocumentation: false, - hasReadme: false, - numberOfContributors: 0, - hasTestTargets: false)).score, - 107) - XCTAssertEqual(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, - releaseCount: 20, - likeCount: 20_000, - isArchived: false, - numberOfDependencies: 2, - lastActivityAt: .t0.adding(days: -10), - hasDocumentation: false, - hasReadme: false, - numberOfContributors: 0, - hasTestTargets: true)).score, - 112) - XCTAssertEqual(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, - releaseCount: 20, - likeCount: 20_000, - isArchived: false, - numberOfDependencies: 2, - lastActivityAt: .t0.adding(days: -10), - hasDocumentation: false, - hasReadme: true, - numberOfContributors: 0, - hasTestTargets: false)).score, - 122) - } + @Test(.dependency(\.date.now, .t0)) + func computeBreakdown() throws { + #expect(Score.computeBreakdown(.init(licenseKind: .none, + releaseCount: 0, + likeCount: 0, + isArchived: false, + numberOfDependencies: nil, + lastActivityAt: .t0.adding(days: -400), + hasDocumentation: false, + hasReadme: false, + numberOfContributors: 0, + hasTestTargets: false)).score == 20) + #expect(Score.computeBreakdown(.init(licenseKind: .incompatibleWithAppStore, + releaseCount: 0, + likeCount: 0, + isArchived: false, + numberOfDependencies: nil, + lastActivityAt: .t0.adding(days: -400), + hasDocumentation: false, + hasReadme: false, + numberOfContributors: 0, + hasTestTargets: false)).score == 23) + #expect(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, + releaseCount: 0, + likeCount: 0, + isArchived: false, + numberOfDependencies: nil, + lastActivityAt: .t0.adding(days: -400), + hasDocumentation: false, + hasReadme: false, + numberOfContributors: 0, + hasTestTargets: false)).score == 30) + #expect(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, + releaseCount: 10, + likeCount: 0, + isArchived: false, + numberOfDependencies: nil, + lastActivityAt: .t0.adding(days: -400), + hasDocumentation: false, + hasReadme: false, + numberOfContributors: 0, + hasTestTargets: false)).score == 40) + #expect(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, + releaseCount: 10, + likeCount: 50, + isArchived: false, + numberOfDependencies: nil, + lastActivityAt: .t0.adding(days: -400), + hasDocumentation: false, + hasReadme: false, + numberOfContributors: 0, + hasTestTargets: false)).score == 50) + #expect(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, + releaseCount: 10, + likeCount: 50, + isArchived: true, + numberOfDependencies: nil, + lastActivityAt: .t0.adding(days: -400), + hasDocumentation: false, + hasReadme: false, + numberOfContributors: 0, + hasTestTargets: false)).score == 30) + #expect(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, + releaseCount: 20, + likeCount: 20_000, + isArchived: false, + numberOfDependencies: nil, + lastActivityAt: .t0.adding(days: -400), + hasDocumentation: false, + hasReadme: false, + numberOfContributors: 0, + hasTestTargets: false)).score == 87) + #expect(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, + releaseCount: 20, + likeCount: 20_000, + isArchived: false, + numberOfDependencies: 4, + lastActivityAt: .t0.adding(days: -400), + hasDocumentation: false, + hasReadme: false, + numberOfContributors: 0, + hasTestTargets: false)).score == 89) + #expect(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, + releaseCount: 20, + likeCount: 20_000, + isArchived: false, + numberOfDependencies: 2, + lastActivityAt: .t0.adding(days: -400), + hasDocumentation: false, + hasReadme: false, + numberOfContributors: 0, + hasTestTargets: false)).score == 92) + #expect(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, + releaseCount: 20, + likeCount: 20_000, + isArchived: false, + numberOfDependencies: 2, + lastActivityAt: .t0.adding(days: -400), + hasDocumentation: false, + hasReadme: false, + numberOfContributors: 0, + hasTestTargets: false)).score == 92) + #expect(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, + releaseCount: 20, + likeCount: 20_000, + isArchived: false, + numberOfDependencies: 2, + lastActivityAt: .t0.adding(days: -300), + hasDocumentation: false, + hasReadme: false, + numberOfContributors: 0, + hasTestTargets: false)).score == 97) + #expect(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, + releaseCount: 20, + likeCount: 20_000, + isArchived: false, + numberOfDependencies: 2, + lastActivityAt: .t0.adding(days: -100), + hasDocumentation: false, + hasReadme: false, + numberOfContributors: 0, + hasTestTargets: false)).score == 102) + #expect(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, + releaseCount: 20, + likeCount: 20_000, + isArchived: false, + numberOfDependencies: 2, + lastActivityAt: .t0.adding(days: -10), + hasDocumentation: false, + hasReadme: false, + numberOfContributors: 0, + hasTestTargets: false)).score == 107) + #expect(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, + releaseCount: 20, + likeCount: 20_000, + isArchived: false, + numberOfDependencies: 2, + lastActivityAt: .t0.adding(days: -10), + hasDocumentation: true, + hasReadme: false, + numberOfContributors: 0, + hasTestTargets: false)).score == 122) + #expect(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, + releaseCount: 20, + likeCount: 20_000, + isArchived: false, + numberOfDependencies: 2, + lastActivityAt: .t0.adding(days: -10), + hasDocumentation: true, + hasReadme: false, + numberOfContributors: 5, + hasTestTargets: false)).score == 127) + #expect(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, + releaseCount: 20, + likeCount: 20_000, + isArchived: false, + numberOfDependencies: 2, + lastActivityAt: .t0.adding(days: -10), + hasDocumentation: true, + hasReadme: false, + numberOfContributors: 20, + hasTestTargets: false)).score == 132) + #expect(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, + releaseCount: 20, + likeCount: 20_000, + isArchived: false, + numberOfDependencies: 2, + lastActivityAt: .t0.adding(days: -10), + hasDocumentation: false, + hasReadme: false, + numberOfContributors: 0, + hasTestTargets: false)).score == 107) + #expect(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, + releaseCount: 20, + likeCount: 20_000, + isArchived: false, + numberOfDependencies: 2, + lastActivityAt: .t0.adding(days: -10), + hasDocumentation: false, + hasReadme: false, + numberOfContributors: 0, + hasTestTargets: true)).score == 112) + #expect(Score.computeBreakdown(.init(licenseKind: .compatibleWithAppStore, + releaseCount: 20, + likeCount: 20_000, + isArchived: false, + numberOfDependencies: 2, + lastActivityAt: .t0.adding(days: -10), + hasDocumentation: false, + hasReadme: true, + numberOfContributors: 0, + hasTestTargets: false)).score == 122) } - func test_computeDetails() async throws { - try await withDependencies { - $0.date.now = .now - } operation: { + @Test(.dependency(\.date.now, .now)) + func computeDetails() async throws { + try await withApp { app in // setup let pkg = try await savePackage(on: app.db, "1") try await Repository(package: pkg, defaultBranch: "default", stars: 10_000).save(on: app.db) @@ -260,23 +236,22 @@ class ScoreTests: AppTestCase { let details = Score.computeDetails(repo: jpr.repository, versions: versions) do { // validate - let details = try XCTUnwrap(details) - XCTAssertEqual(details.scoreBreakdown, [ + let details = try #require(details) + #expect(details.scoreBreakdown == [ .archive: 20, .dependencies: 5, .documentation: 15, .releases: 20, .stars: 37, ]) - XCTAssertEqual(details.score, 97) + #expect(details.score == 97) } } } - func test_computeDetails_unknown_resolvedDependencies() async throws { - try await withDependencies { - $0.date.now = .now - } operation: { + @Test(.dependency(\.date.now, .now)) + func computeDetails_unknown_resolvedDependencies() async throws { + try await withApp { app in // setup let pkg = try await savePackage(on: app.db, "1") try await Repository(package: pkg, defaultBranch: "default", stars: 10_000).save(on: app.db) @@ -296,15 +271,15 @@ class ScoreTests: AppTestCase { let details = Score.computeDetails(repo: jpr.repository, versions: versions) do { // validate - let details = try XCTUnwrap(details) - XCTAssertEqual(details.scoreBreakdown, [ + let details = try #require(details) + #expect(details.scoreBreakdown == [ .archive: 20, // no .dependencies category .documentation: 15, .releases: 20, .stars: 37, ]) - XCTAssertEqual(details.score, 92) + #expect(details.score == 92) } } } diff --git a/Tests/AppTests/__Snapshots__/RSSTests/test_recentPackages.1.xml b/Tests/AppTests/__Snapshots__/RSSTests/recentPackages.1.xml similarity index 100% rename from Tests/AppTests/__Snapshots__/RSSTests/test_recentPackages.1.xml rename to Tests/AppTests/__Snapshots__/RSSTests/recentPackages.1.xml diff --git a/Tests/AppTests/__Snapshots__/RSSTests/test_recentReleases.1.xml b/Tests/AppTests/__Snapshots__/RSSTests/recentReleases.1.xml similarity index 100% rename from Tests/AppTests/__Snapshots__/RSSTests/test_recentReleases.1.xml rename to Tests/AppTests/__Snapshots__/RSSTests/recentReleases.1.xml diff --git a/Tests/AppTests/__Snapshots__/RSSTests/test_recentReleases_route_all.1.xml b/Tests/AppTests/__Snapshots__/RSSTests/recentReleases_route_all.1.xml similarity index 100% rename from Tests/AppTests/__Snapshots__/RSSTests/test_recentReleases_route_all.1.xml rename to Tests/AppTests/__Snapshots__/RSSTests/recentReleases_route_all.1.xml diff --git a/Tests/AppTests/__Snapshots__/RSSTests/test_recentReleases_route_major.1.xml b/Tests/AppTests/__Snapshots__/RSSTests/recentReleases_route_major.1.xml similarity index 100% rename from Tests/AppTests/__Snapshots__/RSSTests/test_recentReleases_route_major.1.xml rename to Tests/AppTests/__Snapshots__/RSSTests/recentReleases_route_major.1.xml diff --git a/Tests/AppTests/__Snapshots__/RSSTests/test_recentReleases_route_majorMinor.1.xml b/Tests/AppTests/__Snapshots__/RSSTests/recentReleases_route_majorMinor.1.xml similarity index 100% rename from Tests/AppTests/__Snapshots__/RSSTests/test_recentReleases_route_majorMinor.1.xml rename to Tests/AppTests/__Snapshots__/RSSTests/recentReleases_route_majorMinor.1.xml diff --git a/Tests/AppTests/__Snapshots__/RSSTests/test_recentReleases_route_preRelease.1.xml b/Tests/AppTests/__Snapshots__/RSSTests/recentReleases_route_preRelease.1.xml similarity index 100% rename from Tests/AppTests/__Snapshots__/RSSTests/test_recentReleases_route_preRelease.1.xml rename to Tests/AppTests/__Snapshots__/RSSTests/recentReleases_route_preRelease.1.xml diff --git a/Tests/AppTests/__Snapshots__/RSSTests/test_render_feed.1.xml b/Tests/AppTests/__Snapshots__/RSSTests/render_feed.1.xml similarity index 100% rename from Tests/AppTests/__Snapshots__/RSSTests/test_render_feed.1.xml rename to Tests/AppTests/__Snapshots__/RSSTests/render_feed.1.xml diff --git a/Tests/AppTests/__Snapshots__/RSSTests/test_render_item.1.xml b/Tests/AppTests/__Snapshots__/RSSTests/render_item.1.xml similarity index 100% rename from Tests/AppTests/__Snapshots__/RSSTests/test_render_item.1.xml rename to Tests/AppTests/__Snapshots__/RSSTests/render_item.1.xml