Skip to content

test(storage): migrate StorageTests to Swift Testing, keep Mocker (Phase 3)#1096

Merged
grdsdev merged 2 commits into
mainfrom
test/sdk-1250-storage-swift-testing-migration
Jul 21, 2026
Merged

test(storage): migrate StorageTests to Swift Testing, keep Mocker (Phase 3)#1096
grdsdev merged 2 commits into
mainfrom
test/sdk-1250-storage-swift-testing-migration

Conversation

@grdsdev

@grdsdev grdsdev commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Migrates Tests/StorageTests (11 files) from XCTest to Swift Testing (@Suite/@Test), per the repo-wide Swift Testing migration plan (SDK-435) and the conventions decided in Phase 0 (SDK-1247, SDK-1091). Keeps Mocker for HTTP mocking — Replay isn't proven yet for all our cases, so we're sticking with Mocker for now (may revisit later).

Changes

  • Package.swift: Moved StorageTests out of the blanket .swiftLanguageMode(.v5) pin into the swift6TestTargets set, so it now compiles under full Swift 6 language mode with the same strict-concurrency settings as production targets. Dropped the unused CustomDump dependency; kept Mocker/TestHelpers/InlineSnapshotTesting/XCTestDynamicOverlay (all still used). No new package dependency.
  • Tests/StorageTests/: All 11 files converted. Pure-unit files (BucketOptionsTests, FileOptionsTests, TransformOptionsTests, ValueTypesTests, StorageErrorTests, MultipartFormDataTests) are mechanical conversions. DownloadBehaviorTests' setUp became init(). StorageBucketAPITests/StorageFileAPITests (the Mocker-heavy files) converted to @Suite(.serialized) struct with a per-test makeSUT() helper (fresh URLSessionConfiguration + MockingURLProtocol each call), keeping every existing Mock(...).snapshotRequest { ... }.register() curl-body assertion as-is — including for move/copy/remove, no new matching mechanism needed. .serialized is required: Mocker's mock registry is process-global with no per-test isolation, and Swift Testing runs suites in parallel by default. SupabaseStorageTests keeps its existing closure-based StorageHTTPSession mocking (already framework-agnostic) but drops XCTestCase.
  • Removed one orphaned/stale snapshot fixture (StorageBucketAPITests-testCreateBucket.1.txt, didn't match any current test — that test uses an inline .snapshotRequest instead). With the directory now empty, dropped the now-dangling exclude: ["__Snapshots__"] from the target too.

Root cause note (bug found during migration)

While migrating SupabaseStorageTests.uploadData/uploadFileURL, found that the original XCTest mocks wired their response-producing closure to StorageHTTPSession.fetch, not .upload — confirmed this is correct because production Storage code (StorageApi.swift) only ever calls configuration.session.fetch; .upload is currently dead code for all Storage HTTP calls including multipart uploads. Preserved that wiring in the migrated tests.

Test plan

  • swift test --filter StorageTests: 145/145 tests pass (139 from the original conversion + 6 added to main since), run twice to rule out Mocker registry races under parallel execution.
  • swift test (full suite, minus IntegrationTests which needs a local Supabase instance per AGENTS.md): 0 failures.
  • Zero import XCTest remaining in Tests/StorageTests.
  • ./scripts/format.sh clean.

Linear

Closes SDK-1250

@grdsdev
grdsdev requested a review from a team as a code owner July 8, 2026 21:16
@coveralls

coveralls commented Jul 8, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 29818457931

Coverage remained the same at 83.583%

Details

  • Coverage remained the same as the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 9740
Covered Lines: 8141
Line Coverage: 83.58%
Coverage Strength: 38.65 hits per line

💛 - Coveralls

grdsdev added a commit that referenced this pull request Jul 9, 2026
Converts the largest AuthTests file (87 tests, 81 Mocker Mock() calls,
53 curl-snapshot assertions) to Swift Testing + Replay, per the Phase 0
decision (SDK-1247) and the Phase 4/Phase 3 conversion patterns
(PostgRESTTests PR #1095, StorageTests PR #1096).

- Curl-snapshot request-shape assertions dropped per the Phase 0 "no
  shim" decision, replaced by Replay's matcher-based enforcement.
- Query strings preserved via exact-URL matching (.method, .url) rather
  than path-only matching, so query-string regressions are still
  caught (the gap PR #1095's follow-up commit found and fixed).
- Request bodies verified via a custom .custom matcher that decodes
  both sides as AnyJSON for structural comparison (key order/whitespace
  insensitive), following the pattern from StorageTests PR #1096's
  jsonBody(of:) helper -- important here since most of this file's
  Mocker bodies carry auth-relevant payloads (passwords, tokens, PKCE
  code verifiers, MFA/passkey credentials).
- withMainSerialExecutor wrapping moved from XCTestCase.invokeTest into
  the handful of @test bodies that actually spawn concurrent
  authStateChanges-driven Tasks.
- HTTPResponse.stub(...) helper (used cross-file by SessionManagerTests)
  preserved at the bottom of the file.

Linear: SDK-1252
grdsdev added a commit that referenced this pull request Jul 21, 2026
Same Phase 3 migration as #1096, but stays on Mocker for HTTP mocking
instead of Replay -- Replay isn't proven yet for all our cases, so we
stick with Mocker for now. StorageBucketAPITests/StorageFileAPITests
gain @suite(.serialized) since Mocker's mock registry is process-global
and Swift Testing runs suites in parallel by default. Restores the
.snapshotRequest curl-body assertions for move/copy/remove instead of
Replay's custom JSON-body matcher, since Mocker already covers that.

Linear: SDK-1250
@grdsdev
grdsdev force-pushed the test/sdk-1250-storage-swift-testing-migration branch from abeffd9 to 7106c74 Compare July 21, 2026 09:12
Copilot AI review requested due to automatic review settings July 21, 2026 09:12
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 94085889-0e2e-42d7-80ca-6438ded31f55

📥 Commits

Reviewing files that changed from the base of the PR and between b6c379d and c7eed6a.

📒 Files selected for processing (2)
  • Tests/StorageTests/StorageBucketAPITests.swift
  • Tests/StorageTests/StorageFileAPITests.swift

📝 Walkthrough

Summary by CodeRabbit

  • Tests
    • Migrated Storage test suites from XCTest to Swift’s Testing framework.
    • Updated assertions, suite structure, and naming while preserving existing coverage.
    • Added/verified behaviors for signed URL creation (including multiple URLs) and URL query handling.
    • Updated multipart upload and request/header behavior assertions.
  • Chores
    • Enabled Swift 6 checking for the Storage test target.
    • Removed an obsolete test dependency and deleted an outdated bucket-creation HTTP snapshot.

Walkthrough

Migrates the Storage test target from XCTest to Swift Testing using @Suite, @Test, and #expect. Multipart failure assertions use #expect(throws:), while API suites adopt serialized setup, injected sessions, and parameterized tests. Existing mocks, snapshots, URL behavior, value validations, and error coverage are preserved. The package manifest removes CustomDump and enables Swift 6 checking for StorageTests.

Possibly related PRs


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@grdsdev grdsdev changed the title test(storage): migrate StorageTests to Swift Testing (Phase 3) test(storage): migrate StorageTests to Swift Testing, keep Mocker (Phase 3) Jul 21, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Migrates the StorageTests suite (and related FunctionsTests updates) from XCTest to the Swift Testing framework, aligning these test targets with the repo’s Swift 6 test-migration plan and enabling Swift 6 language mode for them via swift6TestTargets.

Changes:

  • Converted Tests/StorageTests and several Tests/FunctionsTests files from XCTestCase to @Suite/@Test with #expect assertions and Swift Testing idioms.
  • Updated Mocker-based API tests to use per-test SUT construction and suite serialization traits intended to avoid parallel-execution races.
  • Adjusted Package.swift test-target dependencies and moved FunctionsTests/StorageTests into the Swift 6 test-target set; updated snapshots accordingly.

Reviewed changes

Copilot reviewed 16 out of 21 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
Package.swift Updates test-target dependencies and enables Swift 6 language mode for FunctionsTests and StorageTests.
Tests/StorageTests/ValueTypesTests.swift Converts value-type unit tests to Swift Testing assertions.
Tests/StorageTests/TransformOptionsTests.swift Converts TransformOptions tests to Swift Testing and adds missing Foundation import.
Tests/StorageTests/SupabaseStorageTests.swift Converts storage client tests to Swift Testing; refactors session mocking to per-test instances.
Tests/StorageTests/StorageFileAPITests.swift Converts Mocker-heavy Storage file API tests to Swift Testing with serialized suite and per-test SUT creation.
Tests/StorageTests/StorageErrorTests.swift Converts StorageError tests to Swift Testing.
Tests/StorageTests/StorageBucketAPITests.swift Converts Mocker-heavy Storage bucket API tests to Swift Testing; replaces looped cases with parameterized tests.
Tests/StorageTests/MultipartFormDataTests.swift Converts multipart form-data tests to Swift Testing, including throws expectations.
Tests/StorageTests/FileOptionsTests.swift Converts FileOptions tests to Swift Testing.
Tests/StorageTests/DownloadBehaviorTests.swift Converts DownloadBehavior URL tests to Swift Testing; moves setup into init().
Tests/StorageTests/BucketOptionsTests.swift Converts BucketOptions tests to Swift Testing.
Tests/StorageTests/Snapshots/StorageBucketAPITests/StorageBucketAPITests-testCreateBucket.1.txt Removes an orphaned/stale snapshot fixture.
Tests/FunctionsTests/RequestTests.swift Converts to Swift Testing and updates SnapshotTesting call-site metadata arguments.
Tests/FunctionsTests/FunctionsErrorTests.swift Converts Functions error tests to Swift Testing.
Tests/FunctionsTests/FunctionsClientTests.swift Converts Mocker-heavy Functions client tests to Swift Testing with serialized suite and per-test SUT creation.
Tests/FunctionsTests/FunctionInvokeOptionsTests.swift Converts invoke-options tests to Swift Testing.
Tests/FunctionsTests/Snapshots/RequestTests/invokeWithDefaultOptions.1.txt Adds SnapshotTesting fixture for default invoke request.
Tests/FunctionsTests/Snapshots/RequestTests/invokeWithCustomRegion.1.txt Adds SnapshotTesting fixture for custom region invoke request.
Tests/FunctionsTests/Snapshots/RequestTests/invokeWithCustomMethod.1.txt Adds SnapshotTesting fixture for custom method invoke request.
Tests/FunctionsTests/Snapshots/RequestTests/invokeWithCustomHeader.1.txt Adds SnapshotTesting fixture for custom header invoke request.
Tests/FunctionsTests/Snapshots/RequestTests/invokeWithBody.1.txt Adds SnapshotTesting fixture for invoke request with JSON body.

Comment thread Tests/StorageTests/StorageBucketAPITests.swift Outdated
Comment thread Tests/StorageTests/StorageFileAPITests.swift Outdated
Comment thread Tests/FunctionsTests/FunctionsClientTests.swift Outdated
Same Phase 3 migration as #1096, but stays on Mocker for HTTP mocking
instead of Replay -- Replay isn't proven yet for all our cases, so we
stick with Mocker for now. StorageBucketAPITests/StorageFileAPITests
gain @suite(.serialized) since Mocker's mock registry is process-global
and Swift Testing runs suites in parallel by default. Restores the
.snapshotRequest curl-body assertions for move/copy/remove instead of
Replay's custom JSON-body matcher, since Mocker already covers that.

Linear: SDK-1250
Copilot AI review requested due to automatic review settings July 21, 2026 09:18
@grdsdev
grdsdev force-pushed the test/sdk-1250-storage-swift-testing-migration branch from 7106c74 to b6c379d Compare July 21, 2026 09:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (2)

Tests/StorageTests/StorageBucketAPITests.swift:28

  • Mock registrations are stored in Mocker’s process-global registry; since this suite no longer calls Mocker.removeAll() between tests, stubs can leak across tests and cause unexpected matches (especially for shared URLs like /bucket). Clearing the registry at the start of makeSUT() restores per-test isolation.
  private func makeSUT() -> SupabaseStorageClient {
    let configuration = URLSessionConfiguration.ephemeral
    configuration.protocolClasses = [MockingURLProtocol.self]
    let session = URLSession(configuration: configuration)

Tests/StorageTests/StorageFileAPITests.swift:30

  • This suite registers many Mocker stubs, but there’s no longer a Mocker.removeAll() between tests. Because Mocker’s registry is process-global, stubs can persist and interfere with later tests (or mask missing stubs). Clearing the registry at the start of makeSUT() helps keep tests independent.
  private func makeSUT() -> SupabaseStorageClient {
    let configuration = URLSessionConfiguration.ephemeral
    configuration.protocolClasses = [MockingURLProtocol.self]
    let session = URLSession(configuration: configuration)

Comment on lines 82 to +84
let encodedString = String(data: encoded, encoding: .utf8)
XCTAssertNotNil(encodedString)
XCTAssertTrue(encodedString!.contains(formData.boundary))
#expect(encodedString != nil)
#expect(encodedString!.contains(formData.boundary))
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Capability matrix drift detected

The following capabilities are marked implemented in the matrix but could not be found in swift:

  • auth.mfa.enroll → expected symbol: AuthMFA.enrollWebAuthnFactor
  • auth.mfa.verify → expected symbol: AuthMFA.verifyWebAuthnFactor
  • auth.passkey.register_passkey → expected symbol: AuthClient.registerPasskey
  • auth.passkey.register_passkey → expected symbol: AuthClient.getPasskeyRegistrationOptions
  • auth.passkey.register_passkey → expected symbol: AuthClient.verifyPasskeyRegistration
  • auth.passkey.sign_in_with_passkey → expected symbol: AuthClient.signInWithPasskey
  • auth.passkey.sign_in_with_passkey → expected symbol: AuthClient.getPasskeyAuthenticationOptions
  • auth.passkey.sign_in_with_passkey → expected symbol: AuthClient.verifyPasskeyAuthentication
  • realtime.subscriptions.broadcast → expected symbol: BroadcastJoinConfig.encode

The following capabilities are marked implemented in swift but have no registered symbols to verify:

  • client.authentication_integration.third_party_auth (no symbols list — cannot confirm implementation exists)
  • client.authentication_integration.cross_client_token_sync (no symbols list — cannot confirm implementation exists)
  • client.authentication_integration.oauth_flow_type (no symbols list — cannot confirm implementation exists)
  • client.authentication_integration.session_url_detection (no symbols list — cannot confirm implementation exists)
  • client.session_management.custom_storage (no symbols list — cannot confirm implementation exists)
  • client.session_management.persist_session (no symbols list — cannot confirm implementation exists)
  • client.request_configuration.global_headers (no symbols list — cannot confirm implementation exists)
  • client.observability.trace_propagation (no symbols list — cannot confirm implementation exists)
  • database.query.from_table (no symbols list — cannot confirm implementation exists)
  • database.query.select (no symbols list — cannot confirm implementation exists)
  • database.query.schema_selection (no symbols list — cannot confirm implementation exists)
  • database.query.rpc (no symbols list — cannot confirm implementation exists)
  • database.mutate.insert (no symbols list — cannot confirm implementation exists)
  • database.mutate.update (no symbols list — cannot confirm implementation exists)
  • database.mutate.upsert (no symbols list — cannot confirm implementation exists)
  • database.mutate.delete (no symbols list — cannot confirm implementation exists)
  • database.mutate.select_after_mutation (no symbols list — cannot confirm implementation exists)
  • database.using_filters.eq (no symbols list — cannot confirm implementation exists)
  • database.using_filters.neq (no symbols list — cannot confirm implementation exists)
  • database.using_filters.gt (no symbols list — cannot confirm implementation exists)
  • database.using_filters.gte (no symbols list — cannot confirm implementation exists)
  • database.using_filters.lt (no symbols list — cannot confirm implementation exists)
  • database.using_filters.lte (no symbols list — cannot confirm implementation exists)
  • database.using_filters.like (no symbols list — cannot confirm implementation exists)
  • database.using_filters.ilike (no symbols list — cannot confirm implementation exists)
  • database.using_filters.is (no symbols list — cannot confirm implementation exists)
  • database.using_filters.in (no symbols list — cannot confirm implementation exists)
  • database.using_filters.contains (no symbols list — cannot confirm implementation exists)
  • database.using_filters.contained_by (no symbols list — cannot confirm implementation exists)
  • database.using_filters.range_gt (no symbols list — cannot confirm implementation exists)
  • database.using_filters.range_gte (no symbols list — cannot confirm implementation exists)
  • database.using_filters.range_lt (no symbols list — cannot confirm implementation exists)
  • database.using_filters.range_lte (no symbols list — cannot confirm implementation exists)
  • database.using_filters.range_adjacent (no symbols list — cannot confirm implementation exists)
  • database.using_filters.overlaps (no symbols list — cannot confirm implementation exists)
  • database.using_filters.text_search (no symbols list — cannot confirm implementation exists)
  • database.using_filters.match (no symbols list — cannot confirm implementation exists)
  • database.using_filters.not (no symbols list — cannot confirm implementation exists)
  • database.using_filters.or (no symbols list — cannot confirm implementation exists)
  • database.using_filters.raw (no symbols list — cannot confirm implementation exists)
  • database.using_filters.regex (no symbols list — cannot confirm implementation exists)
  • database.using_filters.regex_icase (no symbols list — cannot confirm implementation exists)
  • database.using_filters.is_distinct (no symbols list — cannot confirm implementation exists)
  • database.using_filters.like_all (no symbols list — cannot confirm implementation exists)
  • database.using_filters.like_any (no symbols list — cannot confirm implementation exists)
  • database.using_filters.ilike_all (no symbols list — cannot confirm implementation exists)
  • database.using_filters.ilike_any (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.order (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.limit (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.range (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.single_row (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.strip_nulls (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.format_csv (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.format_geojson (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.max_affected_rows (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.request_cancellation (no symbols list — cannot confirm implementation exists)
  • database.configuration.auto_retry (no symbols list — cannot confirm implementation exists)
  • functions.invocation.invoke (no symbols list — cannot confirm implementation exists)
  • functions.invocation.set_auth_token (no symbols list — cannot confirm implementation exists)
  • functions.invocation.method_override (no symbols list — cannot confirm implementation exists)
  • functions.invocation.streaming_response (no symbols list — cannot confirm implementation exists)
  • functions.invocation.request_cancellation (no symbols list — cannot confirm implementation exists)
  • realtime.client.connect (no symbols list — cannot confirm implementation exists)
  • realtime.client.disconnect (no symbols list — cannot confirm implementation exists)
  • realtime.client.get_channels (no symbols list — cannot confirm implementation exists)
  • realtime.client.remove_channel (no symbols list — cannot confirm implementation exists)
  • realtime.client.remove_all_channels (no symbols list — cannot confirm implementation exists)
  • realtime.client.connection_state (no symbols list — cannot confirm implementation exists)
  • realtime.client.listen_heartbeats (no symbols list — cannot confirm implementation exists)
  • realtime.client.set_auth_token (no symbols list — cannot confirm implementation exists)
  • realtime.client.channel (no symbols list — cannot confirm implementation exists)
  • realtime.channel.subscribe (no symbols list — cannot confirm implementation exists)
  • realtime.channel.unsubscribe (no symbols list — cannot confirm implementation exists)
  • realtime.channel.send (no symbols list — cannot confirm implementation exists)
  • realtime.channel.broadcast_http (no symbols list — cannot confirm implementation exists)
  • realtime.subscriptions.postgres_changes (no symbols list — cannot confirm implementation exists)
  • realtime.subscriptions.subscribe_presence (no symbols list — cannot confirm implementation exists)
  • realtime.subscriptions.private_channel (no symbols list — cannot confirm implementation exists)
  • realtime.subscriptions.broadcast_self (no symbols list — cannot confirm implementation exists)
  • realtime.subscriptions.broadcast_ack (no symbols list — cannot confirm implementation exists)
  • realtime.subscriptions.broadcast_replay (no symbols list — cannot confirm implementation exists)
  • realtime.presence.track (no symbols list — cannot confirm implementation exists)
  • realtime.presence.untrack (no symbols list — cannot confirm implementation exists)
  • realtime.presence.presence_key (no symbols list — cannot confirm implementation exists)
  • realtime.configuration.custom_websocket_transport (no symbols list — cannot confirm implementation exists)
  • realtime.configuration.reconnect_backoff (no symbols list — cannot confirm implementation exists)
  • realtime.configuration.heartbeat_interval (no symbols list — cannot confirm implementation exists)
  • realtime.configuration.access_token_callback (no symbols list — cannot confirm implementation exists)
  • realtime.configuration.deferred_disconnect (no symbols list — cannot confirm implementation exists)
  • realtime.configuration.custom_logger (no symbols list — cannot confirm implementation exists)
  • realtime.configuration.binary_protocol (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.get_bucket (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.list_file_buckets (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.update_bucket (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.delete_file_bucket (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.empty_bucket (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.access_bucket (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.upload (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.download (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.move (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.copy (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.remove (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.create_signed_url (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.create_signed_urls (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.create_signed_upload_url (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.upload_with_signed_url (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.update_file (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.file_exists (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.file_info (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.list_files_paginated (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.copy_cross_bucket (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.move_cross_bucket (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.upload_with_metadata (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.url_cache_nonce (no symbols list — cannot confirm implementation exists)

These may have been renamed, removed, or never registered. Please update the capability matrix.
See: https://github.com/supabase/sdk/blob/main/docs/capability-matrix.md

Mocker.mock(for:) matches the FIRST registered mock for a request, so
a stale stub from an earlier test could shadow a fresh one registered
for the same URL in a later test. Clear the registry at the top of
makeSUT() in both StorageBucketAPITests and StorageFileAPITests.

Since Mocker's registry is process-global, the two suites also can't
run concurrently *with each other* anymore (only .serialized within
each suite isn't enough) -- otherwise one suite's removeAll() could
wipe out mocks the other just registered. Nest both under a shared
StorageMockerTests(.serialized) namespace, since Swift Testing applies
.serialized recursively to nested suites.

Addresses review feedback on #1096.
Copilot AI review requested due to automatic review settings July 21, 2026 09:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Comment thread Tests/StorageTests/StorageBucketAPITests.swift
Comment thread Tests/StorageTests/StorageFileAPITests.swift
grdsdev added a commit that referenced this pull request Jul 21, 2026
Same Phase 2 migration as #1094, but stays on Mocker for HTTP mocking
instead of Replay -- Replay isn't proven yet for all our cases, so we
stick with Mocker for now. FunctionsClientTests gains @suite(.serialized)
since Mocker's mock registry is process-global and Swift Testing runs
suites in parallel by default. makeSUT() also clears the registry via
Mocker.removeAll() up front, since Mocker matches the first registered
stub for a request and a stale one could otherwise shadow a fresh one
(same fix as landed on #1096 after review).

Rebased onto main's x-relay-error-before-status fix (#1112), porting
its two new test cases (invoke_relayErrorWithNon2xxStatus_shouldThrowRelayError,
invokeWithStreamedResponseRelayErrorWithNon2xxStatus) to Swift Testing.

Linear: SDK-1249
@grdsdev
grdsdev enabled auto-merge (squash) July 21, 2026 09:40
@grdsdev
grdsdev merged commit f1cafe8 into main Jul 21, 2026
31 of 32 checks passed
@grdsdev
grdsdev deleted the test/sdk-1250-storage-swift-testing-migration branch July 21, 2026 09:42
Copilot stopped work on behalf of grdsdev due to an error July 21, 2026 09:42
grdsdev added a commit that referenced this pull request Jul 21, 2026
Same Phase 2 migration as #1094, but stays on Mocker for HTTP mocking
instead of Replay -- Replay isn't proven yet for all our cases, so we
stick with Mocker for now. FunctionsClientTests gains @suite(.serialized)
since Mocker's mock registry is process-global and Swift Testing runs
suites in parallel by default. makeSUT() also clears the registry via
Mocker.removeAll() up front, since Mocker matches the first registered
stub for a request and a stale one could otherwise shadow a fresh one
(same fix as landed on #1096 after review).

Rebased onto main's x-relay-error-before-status fix (#1112), porting
its two new test cases (invoke_relayErrorWithNon2xxStatus_shouldThrowRelayError,
invokeWithStreamedResponseRelayErrorWithNon2xxStatus) to Swift Testing.

Linear: SDK-1249
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants