Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot convert value of type 'FileString' (aka 'String') to expected argument type 'StaticString #598

Closed
drekka opened this issue Sep 3, 2018 · 4 comments

Comments

@drekka
Copy link

drekka commented Sep 3, 2018

What did you do?

Am trying to write a custom AssertionHandler for testing some test support functions that generate
Nimble failures. In that code tried to do this:

func assert(_ assertion: Bool, message: FailureMessage, location: SourceLocation) {
        // ... do stuff
        XCTFail(message.stringValue, file: location.file, line: location.line)
    }

What did you expect to happen?

The code should compile.

What actually happened instead?

The compile failed with: Cannot convert value of type 'FileString' (aka 'String') to expected argument type 'StaticString'

Discussion

I found a previous issue (#242) which is this exact problem. The comment log in that suggested to me that it had been fixed, but it appears not.

Environment

List the software versions you're using:

  • Quick: None, using XCTest

  • Nimble: 7.1.3

  • Xcode Version: 10.0 beta 6 (10L232m)

  • Swift Version: 4.2

  • Carthage: 0.30.1

@ikesyo
Copy link
Member

ikesyo commented Sep 3, 2018

We use String as FileString on non-SwiftPM envrionment for Objective-C compatibility (StaticString can't be used in Objective-C):

// Ideally we would always use `StaticString` as the type for tracking the file name
// that expectations originate from, for consistency with `assert` etc. from the
// stdlib, and because recent versions of the XCTest overlay require `StaticString`
// when calling `XCTFail`. Under the Objective-C runtime (i.e. building on Mac), we
// have to use `String` instead because StaticString can't be generated from Objective-C
#if SWIFT_PACKAGE
public typealias FileString = StaticString
#else
public typealias FileString = String
#endif

So you could use recordFailure wrapper instead of the direct XCTFail usage:

public func recordFailure(_ message: String, location: SourceLocation) {
#if SWIFT_PACKAGE
XCTFail("\(message)", file: location.file, line: location.line)
#else
if let testCase = CurrentTestCaseTracker.sharedInstance.currentTestCase {
let line = Int(location.line)
testCase.recordFailure(withDescription: message, inFile: location.file, atLine: line, expected: true)
} else {
let msg = """
Attempted to report a test failure to XCTest while no test case was running. The failure was:
\"\(message)\"
It occurred at: \(location.file):\(location.line)
"""
NSException(name: .internalInconsistencyException, reason: msg, userInfo: nil).raise()
}
#endif
}

@ikesyo
Copy link
Member

ikesyo commented Sep 3, 2018

Oh recordFailure is public only on master 😅

You could use master for now. I'm going to backport #543 into 7.x.

@drekka
Copy link
Author

drekka commented Sep 3, 2018

Thanks. I loaded up the Nimble code downloaded via Carthage and saw that code but I wasn't sure I understood the problem it was solving. I'm running in Xcode against a iOS simulator so I just assumed that FileString would be correct.

I'll try the code you suggested and see how it goes. Thanks.

@drekka
Copy link
Author

drekka commented Sep 3, 2018

I ended up staying on the release code and using:

class AssertionValidator: AssertionHandler {

    private var expectedError: String
    private var testcase: XCTestCase
    
    init(testcase: XCTestCase, expectedError error: String) {
        self.expectedError = error
        self.testcase = testcase
    }
    
    func assert(_ assertion: Bool, message: FailureMessage, location: SourceLocation) {
        if message.stringValue != expectedError {
            testcase.recordFailure(withDescription: message.stringValue, inFile: location.file, atLine: Int(location.line), expected: true)
        }
    }
}

Which is working just fine for me. Thanks for pointing me at that code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants