<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>I would love it if we could do a full review of XCtest in general. As there are other things it could help with I.r mocking or allowing us to express tests in a BDD way <br><br>Sent from my iPhone</div><div><br>On 10 Jan 2016, at 10:29, Drew Crawford via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=utf-8"><div class="">I have on the order of ~700 tests in XCTest in Swift-language projects. I'm considering migrating away from XCTest, although not over this issue.</div><div class=""><br class=""></div><div class="">This proposal IMO addresses an important problem, but I am not convinced it actually solves it. #2 & #3 are basically sound API designs. It is a mystery to me why #3 "generated some debate" as this is a feature I already implement manually, but I can't address unknown concerns. I can tell you I implement this, and nothing terrible has happened to me so far.</div><div class=""><br class=""></div><div class="">#1 I would not use. The rest of this comment explains why.</div><div class=""><br class=""></div><div class="">Currently I write tests about like this:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">try! hopefullyNothingBad()</div></blockquote><div class=""><br class=""></div>Now this is "bad" because it "crashes" but that's (big sigh) actually "good" because the debugger stops and/or I get a crash report that identifies at least "some" line where something bad definitely happened.<div class=""><br class=""></div><div class="">Now that is not everything I <i class="">want</i> to know–I <i class="">want</i> someone to tell me a story of how this error was created deep down in the bowels of my application, how it spent its kindergarten years in the models layer before being passed into a controller where it was rethrown onto a different dispatch queue and finally ended up in my unit test–but we can't have everything. So I settle for collecting a line number from the test case and then going hunting by hand.</div><div class=""><br class=""></div><div class="">When the test function throws we no longer even find out a line number in the test case anymore, because the error is passed into XCTest and the information is lost. We have just the name of the test case (I assume; the proposal is silent on this issue, but that's the only way I can think of to implement it), and some of my tests are pretty long. So, that makes it even harder to track down.</div><div class=""><br class=""></div><div class="">This sounds like a small thing but my test coverage is so thorough on mature projects that mostly what I turn up are heisenbugs that reproduce with 2% probability. So getting the report from the CI that has the most possible detail is critical, because if the report is not thorough enough for you to guess the bug, too bad, because that's all the information you get and the bug is not reproducible.</div><div class=""><br class=""></div><div class="">For that reason, I won't use #1. I hesitate about whether to call it bad idea altogether, or whether it's just not to my taste. My sense is it's probably somewhere in the middle of those two poles.</div><div class=""><br class=""></div><div class="">I would use #2 and #3, assuming that I don't first migrate out to a non-XCTest framework.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 9, 2016, at 8:58 PM, Chris Hanson via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">We’d like feedback on a proposed design for adding support for Swift error handling to XCTest, attached below. I’ll mostly let the proposal speak for itself, but there are three components to it: Allowing test methods to throw errors, allowing the expressions evaluated by assertions to throw errors, and adding an assertion for checking error handling.<div class=""><br class=""></div><div class="">We’d love to hear your feedback. We’re particularly interested in some feedback on the idea of allowing the expressions evaluated by assertions to throw errors; it’s generated some debate because it results in writing test code slightly differently than other code that makes use of Swift error handling, so any thoughts on it would be particularly appreciated.<br class=""><div class=""><span style="text-align: right;" class=""><br class=""></span></div><div class=""><div class=""><div class=""><div class=""> -- Chris Hanson (<a href="mailto:chanson@apple.com" class="">chanson@apple.com</a>)</div><div class=""><div class=""><div class=""><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><h1 id="toc_0" style="-webkit-print-color-adjust: exact; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 28px; font-family: Helvetica, arial, sans-serif; background-color: rgb(255, 255, 255); margin-top: 0px !important;" class="">XCTest Support for Swift Error Handling</h1><ul style="-webkit-print-color-adjust: exact; margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class=""><li style="-webkit-print-color-adjust: exact; margin: 0px;" class="">Proposal: <a href="https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md" style="-webkit-print-color-adjust: exact; color: rgb(65, 131, 196); margin-top: 0px;" class="">SE-NNNN</a></li><li style="-webkit-print-color-adjust: exact; margin: 0px;" class="">Author(s): <a href="https://github.com/eschaton" style="-webkit-print-color-adjust: exact; color: rgb(65, 131, 196); margin-top: 0px;" class="">Chris Hanson</a></li><li style="-webkit-print-color-adjust: exact; margin: 0px;" class="">Status: <strong style="-webkit-print-color-adjust: exact; margin-top: 0px;" class="">Review</strong></li><li style="-webkit-print-color-adjust: exact; margin: 0px;" class="">Review manager: TBD</li></ul><h2 id="toc_1" style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 24px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, sans-serif; background-color: rgb(255, 255, 255);" class="">Introduction</h2><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">Swift 2 introduced a new error handling mechanism that, for completeness, needs to be accommodated by our testing frameworks. Right now, to write tests that involve methods that may throw an error, a developer needs to incorporate significant boilerplate into their test. We should move this into the framework in several ways, so tests of code that interacts with Swift error handling is concise and intention-revealing.</p><h2 id="toc_2" style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 24px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, sans-serif; background-color: rgb(255, 255, 255);" class="">Motivation</h2><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">Currently, if a developer wants to use a call that may throw an error in a test, they need to use Swift's <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">do..catch</code> construct in their test because tests are not themselves allowed to throw errors.</p><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">As an example, a vending machine object that has had insufficient funds deposited may throw an error if asked to vend an item. A test for that situation could reasonably use the <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">do..catch</code>construct to check that this occurs as expected. However, that means all other tests <em style="-webkit-print-color-adjust: exact;" class="">also</em> need to use either a <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">do..catch</code> or <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">try!</code> construct — and the failure of a <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">try!</code> is catastrophic, so <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">do..catch</code> would be preferred simply for better reporting within tests.</p><pre class=" language-swift" style="-webkit-print-color-adjust: exact; margin-top: 0.5em; margin-bottom: 0.5em; background-color: rgb(245, 242, 240); border: 1px solid rgb(204, 204, 204); font-size: 13px; line-height: 1.5; overflow: auto; padding: 1em; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; text-shadow: white 0px 1px; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; direction: ltr; word-break: normal; word-wrap: normal; tab-size: 4; -webkit-hyphens: none;"><code class=" language-swift" style="-webkit-print-color-adjust: exact; margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; text-shadow: white 0px 1px; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; line-height: 1.5; tab-size: 4; -webkit-hyphens: none;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">func</span> <span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">testVendingOneItem</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">{</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">do</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">{</span>
vendingMachine<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">deposit</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span><span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">5</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">let</span> item <span class="token operator" style="-webkit-print-color-adjust: exact; color: rgb(166, 127, 89); background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">try</span> vendingMachine<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">vend</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span>row<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">:</span> <span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">1</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">,</span> column<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">:</span> <span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">1</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span>
<span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">XCTAssertEqual</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span>item<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">,</span> <span class="token string" style="-webkit-print-color-adjust: exact; color: rgb(102, 153, 0);">"Candy Bar"</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">}</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">catch</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">{</span>
<span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">XCTFail</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span><span class="token string" style="-webkit-print-color-adjust: exact; color: rgb(102, 153, 0);">"Unexpected failure: <span class="token interpolation" style="-webkit-print-color-adjust: exact;"><span class="token delimiter variable" style="-webkit-print-color-adjust: exact; color: rgb(238, 153, 0);">\(</span>error<span class="token delimiter variable" style="-webkit-print-color-adjust: exact; color: rgb(238, 153, 0);">)</span></span>"</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">}</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">}</span></code></pre><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">If the implementation of <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">VendingMachine.vend(row:column:)</code> changes during development such that it throws an error in this situation, the test will fail as it should.</p><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">One other downside of the above is that a failure caught this way will be reported as an <em style="-webkit-print-color-adjust: exact;" class="">expected failure</em>, which would normally be a failure for which XCTest is explicitly testing via an assertion. This failure should ideally be treated as an <em style="-webkit-print-color-adjust: exact;" class="">unexpected failure</em>, as it's not one that's anticipated in the execution of the test.</p><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">In addition, tests do not currently support throwing an error from within an assertion, requiring any code that throws an error to be invoked outside the assertion itself using the same techniques described above.</p><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">Finally, since Swift error handling is a general mechanism that developers should be implementing in their own applications and frameworks, we need to make it straightforward to write tests that ensure code that implements error handling does so correctly.</p><h2 id="toc_3" style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 24px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, sans-serif; background-color: rgb(255, 255, 255);" class="">Proposed solution</h2><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">I propose several related solutions to this issue:</p><ol style="-webkit-print-color-adjust: exact; margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class=""><li style="-webkit-print-color-adjust: exact; margin: 0px;" class="">Allow test methods to throw errors.</li><li style="-webkit-print-color-adjust: exact; margin: 0px;" class="">Allow test assertion expressions to throw errors.</li><li style="-webkit-print-color-adjust: exact; margin: 0px;" class="">Add an assertion for checking errors.</li></ol><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">These solutions combine to make writing tests that involve thrown errors much more succinct.</p><h4 id="toc_4" style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 16px; font-family: Helvetica, arial, sans-serif; background-color: rgb(255, 255, 255);" class="">Allowing Test Methods to Throw Errors</h4><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">First, we can allow test methods to throw errors if desired, thus allowing the <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">do..catch</code> construct to be omitted when the test isn't directly checking error handling. This makes the code a developer writes when they're not explicitly trying to test error handling much cleaner.</p><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">Moving the handling of errors thrown by tests into XCTest itself also ensures they can be treated as unexpected failures, since the mechanism to do so is currently private to the framework.</p><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">With this, the test from the previous section can become:</p><pre class=" language-swift" style="-webkit-print-color-adjust: exact; margin-top: 0.5em; margin-bottom: 0.5em; background-color: rgb(245, 242, 240); border: 1px solid rgb(204, 204, 204); font-size: 13px; line-height: 1.5; overflow: auto; padding: 1em; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; text-shadow: white 0px 1px; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; direction: ltr; word-break: normal; word-wrap: normal; tab-size: 4; -webkit-hyphens: none;"><code class=" language-swift" style="-webkit-print-color-adjust: exact; margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; text-shadow: white 0px 1px; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; line-height: 1.5; tab-size: 4; -webkit-hyphens: none;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">func</span> <span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">testVendingOneItem</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">throws</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">{</span>
vendingMachine<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">deposit</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span><span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">5</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">let</span> item <span class="token operator" style="-webkit-print-color-adjust: exact; color: rgb(166, 127, 89); background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">try</span> vendingMachine<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">vend</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span>row<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">:</span> <span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">1</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">,</span> column<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">:</span> <span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">1</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span>
<span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">XCTAssertEqual</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span>item<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">,</span> <span class="token string" style="-webkit-print-color-adjust: exact; color: rgb(102, 153, 0);">"Candy Bar"</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">}</span></code></pre><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">This shows much more directly that the test is intended to check a specific non-error case, and that the developer is relying on the framework to handle unexpected errors.</p><h4 id="toc_5" style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 16px; font-family: Helvetica, arial, sans-serif; background-color: rgb(255, 255, 255);" class="">Allowing Test Assertions to Throw Errors</h4><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">We can also allow the <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">@autoclosure</code> expression that is passed into an assertion to throw an error, and treat that error as an unexpected failure (since the code is being invoked in an assertion that isn't directly related to error handling). For example:</p><pre class=" language-swift" style="-webkit-print-color-adjust: exact; margin-top: 0.5em; margin-bottom: 0.5em; background-color: rgb(245, 242, 240); border: 1px solid rgb(204, 204, 204); font-size: 13px; line-height: 1.5; overflow: auto; padding: 1em; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; text-shadow: white 0px 1px; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; direction: ltr; word-break: normal; word-wrap: normal; tab-size: 4; -webkit-hyphens: none;"><code class=" language-swift" style="-webkit-print-color-adjust: exact; margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; text-shadow: white 0px 1px; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; line-height: 1.5; tab-size: 4; -webkit-hyphens: none;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">func</span> <span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">testVendingMultipleItemsWithSufficientFunds</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">{</span>
vendingMachine<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">deposit</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span><span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">10</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span>
<span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">XCTAssertEqual</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span><span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">try</span> vendingMachine<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">vend</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span>row<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">:</span> <span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">1</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">,</span> column<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">:</span> <span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">1</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">,</span> <span class="token string" style="-webkit-print-color-adjust: exact; color: rgb(102, 153, 0);">"Candy Bar"</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span>
<span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">XCTAssertEqual</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span><span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">try</span> vendingMachine<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">vend</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span>row<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">:</span> <span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">1</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">,</span> column<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">:</span> <span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">2</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">,</span> <span class="token string" style="-webkit-print-color-adjust: exact; color: rgb(102, 153, 0);">"Chips"</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">}</span></code></pre><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">This can eliminate otherwise-dangerous uses of <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">try!</code> and streamline code that needs to make multiple assertions in a row.</p><h4 id="toc_6" style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 16px; font-family: Helvetica, arial, sans-serif; background-color: rgb(255, 255, 255);" class="">Adding a "Throws Error" Assertion</h4><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">In order to test code that throws an error, it would be useful to have an assertion that expects an error to be thrown in a particular case. Right now a developer writing code to test that an error is thrown has to test that error themselves:</p><pre class=" language-swift" style="-webkit-print-color-adjust: exact; margin-top: 0.5em; margin-bottom: 0.5em; background-color: rgb(245, 242, 240); border: 1px solid rgb(204, 204, 204); font-size: 13px; line-height: 1.5; overflow: auto; padding: 1em; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; text-shadow: white 0px 1px; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; direction: ltr; word-break: normal; word-wrap: normal; tab-size: 4; -webkit-hyphens: none;"><code class=" language-swift" style="-webkit-print-color-adjust: exact; margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; text-shadow: white 0px 1px; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; line-height: 1.5; tab-size: 4; -webkit-hyphens: none;"> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">func</span> <span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">testVendingFailsWithInsufficientFunds</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">{</span>
vendingMachine<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">deposit</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span><span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">1</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">var</span> vendingFailed <span class="token operator" style="-webkit-print-color-adjust: exact; color: rgb(166, 127, 89); background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial;">=</span> <span class="token boolean" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">false</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">do</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">{</span>
<span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">_</span> <span class="token operator" style="-webkit-print-color-adjust: exact; color: rgb(166, 127, 89); background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">try</span> vendingMachine<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">vend</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span>row<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">:</span> <span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">1</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">,</span> column<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">:</span> <span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">1</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">}</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">catch</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">{</span>
vendingFailed <span class="token operator" style="-webkit-print-color-adjust: exact; color: rgb(166, 127, 89); background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial;">=</span> <span class="token boolean" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">true</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">}</span>
<span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">XCTAssert</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span>vendingFailed<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">}</span></code></pre><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">If we add an assertion that specifically checks whether an error was thrown, this code will be significantly streamlined:</p><pre class=" language-swift" style="-webkit-print-color-adjust: exact; margin-top: 0.5em; margin-bottom: 0.5em; background-color: rgb(245, 242, 240); border: 1px solid rgb(204, 204, 204); font-size: 13px; line-height: 1.5; overflow: auto; padding: 1em; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; text-shadow: white 0px 1px; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; direction: ltr; word-break: normal; word-wrap: normal; tab-size: 4; -webkit-hyphens: none;"><code class=" language-swift" style="-webkit-print-color-adjust: exact; margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; text-shadow: white 0px 1px; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; line-height: 1.5; tab-size: 4; -webkit-hyphens: none;"> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">func</span> <span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">testVendingFailsWithInsufficientFunds</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">{</span>
vendingMachine<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">deposit</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span><span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">1</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span>
<span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">XCTAssertThrowsError</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span><span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">_</span> <span class="token operator" style="-webkit-print-color-adjust: exact; color: rgb(166, 127, 89); background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">try</span> vendingMachine<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">vend</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span>row<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">:</span> <span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">1</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">,</span> column<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">:</span> <span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">1</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">}</span></code></pre><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">Of course, some code may want to just detect that an error was thrown, but other code may need to check that the details of the thrown error are correct. We can take advantage of Swift's trailing closure syntax to enable this, by passing the thrown error (if any) to a closure that can itself contain assertions:</p><pre class=" language-swift" style="-webkit-print-color-adjust: exact; margin-top: 0.5em; margin-bottom: 0.5em; background-color: rgb(245, 242, 240); border: 1px solid rgb(204, 204, 204); font-size: 13px; line-height: 1.5; overflow: auto; padding: 1em; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; text-shadow: white 0px 1px; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; direction: ltr; word-break: normal; word-wrap: normal; tab-size: 4; -webkit-hyphens: none;"><code class=" language-swift" style="-webkit-print-color-adjust: exact; margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; text-shadow: white 0px 1px; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; line-height: 1.5; tab-size: 4; -webkit-hyphens: none;"> <span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">XCTAssertThrowsError</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span><span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">_</span> <span class="token operator" style="-webkit-print-color-adjust: exact; color: rgb(166, 127, 89); background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">try</span> vendingMachine<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">vend</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span>row<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">:</span> <span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">1</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">,</span> column<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">:</span> <span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">1</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">{</span> error <span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">in</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">guard</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">let</span> vendingError <span class="token operator" style="-webkit-print-color-adjust: exact; color: rgb(166, 127, 89); background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial;">=</span> error <span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">as</span><span class="token operator" style="-webkit-print-color-adjust: exact; color: rgb(166, 127, 89); background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial;">?</span> <span class="token builtin" style="-webkit-print-color-adjust: exact; color: rgb(102, 153, 0);">VendingMachineError</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">else</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">{</span>
<span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">XCTFail</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span><span class="token string" style="-webkit-print-color-adjust: exact; color: rgb(102, 153, 0);">"Unexpected type of error thrown: <span class="token interpolation" style="-webkit-print-color-adjust: exact;"><span class="token delimiter variable" style="-webkit-print-color-adjust: exact; color: rgb(238, 153, 0);">\(</span>error<span class="token delimiter variable" style="-webkit-print-color-adjust: exact; color: rgb(238, 153, 0);">)</span></span>"</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">return</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">}</span>
<span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">XCTAssertEquals</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span>vendingError<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">.</span>item<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">,</span> <span class="token string" style="-webkit-print-color-adjust: exact; color: rgb(102, 153, 0);">"Candy Bar"</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span>
<span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">XCTAssertEquals</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span>vendingError<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">.</span>price<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">,</span> <span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">5</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span>
<span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">XCTAssertEquals</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span>vendingError<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">.</span>message<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">,</span> <span class="token string" style="-webkit-print-color-adjust: exact; color: rgb(102, 153, 0);">"A Candy Bar costs 5 coins"</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">}</span></code></pre><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">This lets a developer very concisely describe an error condition for their code, in whatever level of detail they desire.</p><h2 id="toc_7" style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 24px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, sans-serif; background-color: rgb(255, 255, 255);" class="">Detailed design</h2><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">The design of each of the above components is slightly different, based on the functionality provided.</p><h4 id="toc_8" style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 16px; font-family: Helvetica, arial, sans-serif; background-color: rgb(255, 255, 255);" class="">Tests That Throw</h4><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">In order to enable test methods to throw an error, we will need to update XCTest to support test methods with a <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">() throws -> Void</code> signature in addition to test methods with a <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">() -> Void</code>signature as it already supports.</p><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">We will need to ensure tests that do throw an error have that error caught, and that it registers an unexpected failure.</p><h4 id="toc_9" style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 16px; font-family: Helvetica, arial, sans-serif; background-color: rgb(255, 255, 255);" class="">Assertions That Throw</h4><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">In order to allow assertions to throw an exception, we will need to enhance our existing assertions' <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">@autoclosure</code> expression parameters to add <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">throws</code> to their signature.</p><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">Because Swift defines a closure that can throw an error to be a proper supertype of a closure that does not, this <em style="-webkit-print-color-adjust: exact;" class="">will not</em> result in a combinatorial explosion of assertion overrides, and will let developers naturally write code that may throw an error within an assertion.</p><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">We will treat any error thrown from within an assertion expression as an <em style="-webkit-print-color-adjust: exact;" class="">unexpected</em> failure because while all assertions represent a test for some form of failure, they're not specifically checking for a thrown error.</p><h4 id="toc_10" style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 16px; font-family: Helvetica, arial, sans-serif; background-color: rgb(255, 255, 255);" class="">The "Throws Error" Assertion</h4><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">To write tests for code that throws error, we will add a new assertion function to XCTest with the following prototype:</p><pre class=" language-swift" style="-webkit-print-color-adjust: exact; margin-top: 0.5em; margin-bottom: 0.5em; background-color: rgb(245, 242, 240); border: 1px solid rgb(204, 204, 204); font-size: 13px; line-height: 1.5; overflow: auto; padding: 1em; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; text-shadow: white 0px 1px; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; direction: ltr; word-break: normal; word-wrap: normal; tab-size: 4; -webkit-hyphens: none;"><code class=" language-swift" style="-webkit-print-color-adjust: exact; margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; text-shadow: white 0px 1px; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; line-height: 1.5; tab-size: 4; -webkit-hyphens: none;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">public</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">func</span> <span class="token function" style="-webkit-print-color-adjust: exact; color: rgb(221, 74, 104);">XCTAssertThrowsError</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span>
@autoclosure expression<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">:</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">throws</span> <span class="token operator" style="-webkit-print-color-adjust: exact; color: rgb(166, 127, 89); background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial;">-</span><span class="token operator" style="-webkit-print-color-adjust: exact; color: rgb(166, 127, 89); background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial;">></span> <span class="token builtin" style="-webkit-print-color-adjust: exact; color: rgb(102, 153, 0);">Void</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">,</span>
<span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">_</span> message<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">:</span> <span class="token builtin" style="-webkit-print-color-adjust: exact; color: rgb(102, 153, 0);">String</span> <span class="token operator" style="-webkit-print-color-adjust: exact; color: rgb(166, 127, 89); background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial;">=</span> <span class="token string" style="-webkit-print-color-adjust: exact; color: rgb(102, 153, 0);">""</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">,</span>
file<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">:</span> <span class="token builtin" style="-webkit-print-color-adjust: exact; color: rgb(102, 153, 0);">StaticString</span> <span class="token operator" style="-webkit-print-color-adjust: exact; color: rgb(166, 127, 89); background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">__FILE__</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">,</span>
line<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">:</span> <span class="token builtin" style="-webkit-print-color-adjust: exact; color: rgb(102, 153, 0);">UInt</span> <span class="token operator" style="-webkit-print-color-adjust: exact; color: rgb(166, 127, 89); background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">__LINE__</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">,</span>
<span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">_</span> errorHandler<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">:</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">(</span>error<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">:</span> <span class="token builtin" style="-webkit-print-color-adjust: exact; color: rgb(102, 153, 0);">ErrorType</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span> <span class="token operator" style="-webkit-print-color-adjust: exact; color: rgb(166, 127, 89); background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial;">-</span><span class="token operator" style="-webkit-print-color-adjust: exact; color: rgb(166, 127, 89); background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial;">></span> <span class="token builtin" style="-webkit-print-color-adjust: exact; color: rgb(102, 153, 0);">Void</span> <span class="token operator" style="-webkit-print-color-adjust: exact; color: rgb(166, 127, 89); background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial;">=</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">{</span> <span class="token number" style="-webkit-print-color-adjust: exact; color: rgb(153, 0, 85);">_</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: rgb(0, 119, 170);">in</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">}</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: rgb(153, 153, 153);">)</span></code></pre><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">Rather than treat an error thrown from its expression as a failure, this will treat <em style="-webkit-print-color-adjust: exact;" class="">the lack of</em> an error thrown from its expression as an expected failure.</p><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">Furthermore, so long as an error is thrown, the error will be passed to the <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">errorHandler</code> block passed as a trailing closure, where the developer may make further assertions against it.</p><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">In both cases, the new assertion function is generic on an <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">ErrorType</code> in order to ensure that little to no casting will be required in the trailing closure.</p><h2 id="toc_11" style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 24px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, sans-serif; background-color: rgb(255, 255, 255);" class="">Impact on existing code</h2><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">There should be little impact on existing test code because we are only adding features and API, not changing existing features or API.</p><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">All existing tests should continue to work as implemented, and can easily adopt the new conventions we're making available to become more concise and intention-revealing with respect to their error handling as shown above.</p><h2 id="toc_12" style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 24px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, sans-serif; background-color: rgb(255, 255, 255);" class="">Alternatives considered</h2><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">We considered asking developers continue using XCTest as-is, and encouraging them to use Swift's native error handling to both suppress and check the validity of errors. We also considered adding additional ways of registering failures when doing this, so that developers could register unexpected failures themselves.</p><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">While this would result in developers using the language the same way in their tests as in their functional code, this would also result in much more verbose tests. We rejected this approach because such verbosity can be a significant obstacle to testing.</p><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">Making it quick and clean to write tests for error handling could also encourage developers to implement error handling in their code as they need it, rather than to try to work around the feature because of any perceived difficulty in testing.</p><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">We considered adding the ability to check that a specific error was thrown in <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">XCTAssertThrowsError</code>, but this would require the <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">ErrorType</code> passed to also conform to <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Equatable</code>, which is also unnecessary given that this can easily be checked in a trailing closure if desired. (In some cases a developer may just want to ensure <em style="-webkit-print-color-adjust: exact;" class="">an error</em> is thrown rather than <em style="-webkit-print-color-adjust: exact;" class="">a specific error</em> is thrown.)</p><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">We explicitly chose <em style="-webkit-print-color-adjust: exact;" class="">not</em> to offer a comprehensive suite of <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">DoesNotThrowError</code> assertions for XCTest in Swift, though we do offer such <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">DoesNotThrow</code> assertions for XCTest in Objective-C. We feel these are of limited utility given that our plan is for all assertions (except <code style="-webkit-print-color-adjust: exact; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">XCTAssertThrowsError</code>) to treat any thrown error as a failure.</p><p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);" class="">We explicitly chose not to offer any additional support for Objective-C exceptions beyond what we already provide: In the Xcode implementation of XCTest, an Objective-C exception that occurs within one of our existing assertions or tests will result in a test failure; doing more than this is not practical given that it's possible to neither catch and handle nor generate an Objective-C exception in Swift.</p></div></div></div></div></div></div></div></div>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=OtwgWwWn2mvmck2XIGZZg64wEmoo4f4ILYe4SqMqwHqfcfuLmH4-2Fdr1c3eLih6cI2aQ28DwPs-2BjzkC1PfxXoLj3XuDomqTNJ5B5Ux32VjiUApmOBMJ-2FhsmzZGtPlvgjtFoARNMxM8mu-2FdL8D7U1y0gCZI1hfdCmk2bFbcZB76vyPUXc91NuhiCxh2BTfMUN2eTIjEHHtgRRHIwB3lkbbBQ8HJarstwEBVTycjoVHipk-3D" alt="" width="1" height="1" border="0" style="height:1px !important;width:1px !important;border-width:0 !important;margin-top:0 !important;margin-bottom:0 !important;margin-right:0 !important;margin-left:0 !important;padding-top:0 !important;padding-bottom:0 !important;padding-right:0 !important;padding-left:0 !important;" class="">
</div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=xV0JY-2FdZMnUMvSFtZnLiBPRTDDOSQf3-2FpH33HYOlBxFMEEJYY72kl0fyew-2BVxOAF-2By78SOuJn-2B6LumVFaE3apVN3KfpkYK10RFwYralJEvg4RdbeWsQrWCd45K2sJhgTaDQwvyEkzHF4AJ5dim2yGVJCNtDo0rjKHGxcq2bxfhdp-2FDeB1EiYT6rjLiQYeBs7pc9VN992yZBONMnaFdYMsbOLwI6qP895U3F7beLHVRY-3D" alt="" width="1" height="1" border="0" style="height:1px !important;width:1px !important;border-width:0 !important;margin-top:0 !important;margin-bottom:0 !important;margin-right:0 !important;margin-left:0 !important;padding-top:0 !important;padding-bottom:0 !important;padding-right:0 !important;padding-left:0 !important;">
</div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></body></html>