MakeAWishFoundation / SwiftyMocky

Framework for automatic mock generation. Adds a set of handy methods, simplifying testing. One of the best and most complete solutions, including generics support and much more.
MIT License
1.03k stars 104 forks source link

Xcode 16 beta issues #362

Open mapierce opened 3 weeks ago

mapierce commented 3 weeks ago

Generating mocks with version 4.1.0 of SwiftyMocky results in odd behaviour in my test target when using Xcode 16 beta (any version). I get a lot of errors like:

Type 'Any' cannot conform to 'ExpressiblyByArrayLiteral'
Type 'Any' cannot conform to 'ExpressiblyByStringLiteral'
Type 'Any' cannot conform to 'ExpressiblyByIntLiteral'

around lines such as:

dictionary["key"] = value

where dictionary is defined as type [String: Any].

Removing the Mock.generated.swift file from the "Compile Sources" step of the build phases gets rid of these errors and allows it to build (where SwiftMocky isn't used and this the mock file is not depended on).

I attempted to update to 4.2.0 of SwiftyMocky, but running generate results in a large amount of warnings, a sample of which look like:

warning: Failed to unarchive cache for SomeFile1.swift due to error, re-parsing file
warning: Failed to unarchive cache for SomeFile2.swift due to error, re-parsing file
warning: Failed to unarchive cache for SomeFile3.swift due to error, re-parsing file
warning: Failed to unarchive cache for SomeFile4.swift due to error, re-parsing file
warning: Failed to unarchive cache for SomeFile5.swift due to error, re-parsing file
warning: Failed to unarchive cache for SomeFile6.swift due to error, re-parsing file
warning: Failed to unarchive cache for SomeFile7.swift due to error, re-parsing file
warning: Failed to unarchive cache for SomeFile8.swift due to error, re-parsing file
warning: Failed to unarchive cache for SomeFile9.swift due to error, re-parsing file

but then I also get what appear to be Swift 6 concurrency errors like:

/private/var/folders/64/sqh1_t1914v44d7tpgy0cft40000gn/T/SwiftTemplate/1.8.0/Sources/SourceryRuntime/Array+Parallel.swift:21:17: error: mutable capture of 'inout' parameter 'buffer' is not allowed in concurrently-executing code
19 |         return result.withUnsafeMutableBufferPointer { buffer in
20 |             DispatchQueue.concurrentPerform(iterations: buffer.count) { idx in
21 |                 buffer[idx] = transform(self[idx])
   |                 `- error: mutable capture of 'inout' parameter 'buffer' is not allowed in concurrently-executing code
22 |             }
23 |             return buffer.map { $0! }
[42/50] Compiling SourceryRuntime Annotations.swift
/private/var/folders/64/sqh1_t1914v44d7tpgy0cft40000gn/T/SwiftTemplate/1.8.0/Sources/SourceryRuntime/Array+Parallel.swift:21:17: error: mutable capture of 'inout' parameter 'buffer' is not allowed in concurrently-executing code
19 |         return result.withUnsafeMutableBufferPointer { buffer in
20 |             DispatchQueue.concurrentPerform(iterations: buffer.count) { idx in
21 |                 buffer[idx] = transform(self[idx])
   |                 `- error: mutable capture of 'inout' parameter 'buffer' is not allowed in concurrently-executing code
22 |             }
23 |             return buffer.map { $0! }
[43/50] Compiling SourceryRuntime Array+Parallel.swift
/private/var/folders/64/sqh1_t1914v44d7tpgy0cft40000gn/T/SwiftTemplate/1.8.0/Sources/SourceryRuntime/Array+Parallel.swift:21:17: error: mutable capture of 'inout' parameter 'buffer' is not allowed in concurrently-executing code
19 |         return result.withUnsafeMutableBufferPointer { buffer in
20 |             DispatchQueue.concurrentPerform(iterations: buffer.count) { idx in
21 |                 buffer[idx] = transform(self[idx])
   |                 `- error: mutable capture of 'inout' parameter 'buffer' is not allowed in concurrently-executing code
22 |             }
23 |             return buffer.map { $0! }
[44/50] Compiling SourceryRuntime Array.swift
/private/var/folders/64/sqh1_t1914v44d7tpgy0cft40000gn/T/SwiftTemplate/1.8.0/Sources/SourceryRuntime/Array+Parallel.swift:21:17: error: mutable capture of 'inout' parameter 'buffer' is not allowed in concurrently-executing code
19 |         return result.withUnsafeMutableBufferPointer { buffer in
20 |             DispatchQueue.concurrentPerform(iterations: buffer.count) { idx in
21 |                 buffer[idx] = transform(self[idx])
   |                 `- error: mutable capture of 'inout' parameter 'buffer' is not allowed in concurrently-executing code
22 |             }
23 |             return buffer.map { $0! }

So I appear to be fully blocked from running any of my tests on Xcode 16.

Hoping there's a fix for this soon 🙏 as it's a pretty big blocker.

Update

I dug into this a bit and it seems to be related to this issue and SE-0364. It looks like it's occurring as a result of the extensions on the Optional type to add conformance to expressible by string / integer / boolean etc. literal. It looks like the best option in a scenario like this is to create a new wrapper type for optionals instead of explicitly extending the Optional type to work with Parameter. I would suggest something like OptionalParameter which would change the mocked method signature of a function like:

func fetchResults(for searchTerm: String, source: String?)

from this:

public static func fetchResults(for searchTerm: Parameter<String>, source: Parameter<String?>) -> Perform {
    return Perform(method: m_fetchResults__forSearchTermsource, performs: perform)
}

to something like:

public static func fetchResults(for searchTerm: Parameter<String>, source: OptionalParameter<String>) -> Perform {
    return Perform(method: m_fetchResults__forSearchTermsource, performs: perform)
}
kyzmitch commented 2 weeks ago

similar here:

❌  error: SWIFT_VERSION '6.0' is unsupported, supported versions are: 4.0, 4.2, 5.0. (in target 'MyTarget' from project 'myProject')

even if I select Xcode 15.4 which is supported, I guess somehow need to set Swift version to 5.x in Xcode project for the unit tests, but what about the actual module which I want to use 6.0 IDK