Skip to content

Convert JSON/PropertyList tests to swift-testing #1364

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

jmschonfeld
Copy link
Contributor

@jmschonfeld jmschonfeld commented Jun 17, 2025

Continued cherry-picks (with edits) of the initial swift-testing adoption for all of our encoder/decoder-related tests

In particular, this change (in addition to adopting swift-testing):

  • Enables the exit tests previously if-def'ed out in these files (they now pass)
  • Slightly refactors some expectation handling (using #expect(throws:) instead of do/catch with Issue.record for example) for older tests written before these types of expectations existed
  • Removes trivial uses of try!/as! to help trigger expectation failures instead of crashes when unit tests fail
  • Removes accidental uses of Foundation APIs not present in FoundationEssentials (like replacingOccurrences(of:with:) and range(of:))

@jmschonfeld
Copy link
Contributor Author

@swift-ci please test

Copy link
Member

@natecook1000 natecook1000 left a comment

Choose a reason for hiding this comment

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

Looks great! Just a couple notes, but no changes needed 👍🏻

Comment on lines +949 to +951
#expect(throws: Never.self) {
try JSONDecoder().decode(RepeatNilCheckDecodable.self, from: json)
}
Copy link
Member

Choose a reason for hiding this comment

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

Is the idea that this never throws? It might be more clear to mark the function as throws and then just have the code be:

Suggested change
#expect(throws: Never.self) {
try JSONDecoder().decode(RepeatNilCheckDecodable.self, from: json)
}
let _ = try JSONDecoder().decode(RepeatNilCheckDecodable.self, from: json)

Copy link
Member

Choose a reason for hiding this comment

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

Ah, I see that this is a specific Testing pattern. I don't totally get this distinction, but it sounds like what's there is the right code to use!

If the intent is for a test to fail when an error is thrown by expression, rather than to explicitly check that an error is not thrown by it, do not use this macro. Instead, simply call the code in question and allow it to throw an error naturally.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah my thought was that with let _ = try JSONDecoder().decode(RepeatNilCheckDecodable.self, from: json) the intent is a little ambiguous (we don't do anything with the result, so what exactly are we testing?) whereas the #expect(throws: Never.self) makes it explicitly clear that we're testing that this doesn't throw (as opposed to doesn't crash, or doesn't produce some other side effect). We do use the let _ = ... syntax elsewhere, but for cases where we're just testing things that shouldn't crash (but ideally those would have an expectation on the return value as well).

Additionally, if there is an issue, let _ = try ... stops the test immediately and does not attempt the rest of the test, whereas #expect(throws: Never.self) will continue to check other expectations even if this throws, which can get you a more complete story of failures when running in remote environments like CI.

}
}


// MARK: - Helper Global Functions
func XCTAssertEqualPaths(_ lhs: [CodingKey], _ rhs: [CodingKey], _ prefix: String) {
func AssertEqualPaths(_ lhs: [CodingKey], _ rhs: [CodingKey], _ prefix: String) {
Copy link
Member

Choose a reason for hiding this comment

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

Would be nice to augment this with a sourceLocation: SourceLocation = #_sourceLocation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call! I'll update this

@jmschonfeld
Copy link
Contributor Author

@swift-ci please test

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

Successfully merging this pull request may close these issues.

2 participants