I think I probably have some blind spot. The following code in test target actually works that I thought it should not: (MyHelper is private already, but the caller still can use myHelperFunc())
// both MyClass and MyHelper are in the same file
class MyClass: XCTestCase {
func testDoWork() {
MyHelper.myHelperFunc()
}
}
private class MyHelper {
static func myHelperFunc() -> String {
return "something"
}
}
If I move the code to main target (delete the XCTestCase), compiler immediately flag MyHelper is not accessible that seems the right behavior? Is there something specific for test target that I missed?
2
Answers
private
at file scope is equivalent tofileprivate
.@testable import
makesinternal
code accessible to a test target.Access Levels in The Swift Programming Language explains how
private
works:"The enclosing declaration" of MyHelper is "the file." This is perhaps a bit more clearly stated in the Declaration Modifiers section of the Swift Language Reference:
Again, the "enclosing scope" of MyHelper is the file. If MyHelper were enclosed in some other class, then it would be limited to that scope rather than the whole file:
In your example,
myHelperFunc()
has no annotation, so it initially receives the default level ofinternal
. This is noted in Access Levels again:However, as noted in "Guiding Principle of Access Levels:"
It is not allowed for
MyHelper.myHelperFunc()
to have a broader access level than its encoding type (MyHelper), so it’s limited to file scope (which is effectively the same asfileprivate
).